From 9a605f18515228989cbe9f8435d422439b649675 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Mon, 9 Mar 2026 12:44:51 +0000 Subject: [PATCH 1/5] chore: add Boss package manifest Adds boss.json to make this library installable via boss install github.com/freitasjca/Delphi-Cross-Socket Zero source changes. browsingpath includes both Net/ and Utils/ because Net units depend on Utils units at compile time. --- boss.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 boss.json diff --git a/boss.json b/boss.json new file mode 100644 index 0000000..654b250 --- /dev/null +++ b/boss.json @@ -0,0 +1,11 @@ +{ + "name": "delphi-cross-socket", + "description": "Delphi cross-platform async socket library...", + "version": "1.0.0", + "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", + "license": "MIT", + "mainsrc": "Net/", + "browsingpath": "Net/;Utils/", + "projects": [], + "dependencies": {} +} \ No newline at end of file From 7ede4963abb2bf67af8ba499859f884208353dd3 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Mon, 9 Mar 2026 14:39:19 +0000 Subject: [PATCH 2/5] Update description --- boss.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boss.json b/boss.json index 654b250..3afba61 100644 --- a/boss.json +++ b/boss.json @@ -1,6 +1,6 @@ { "name": "delphi-cross-socket", - "description": "Delphi cross-platform async socket library...", + "description": "Delphi cross-platform async socket library (IOCP/epoll/kqueue) with HTTP server and OpenSSL 3.x support. Fork of winddriver/Delphi-Cross-Socket — adds Boss package manifest only. Zero source changes.", "version": "1.0.0", "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", "license": "MIT", From 8cc15ee049810d331d9b5a8a91ab0e4ecc283b5c Mon Sep 17 00:00:00 2001 From: freitasjca Date: Fri, 13 Mar 2026 19:31:45 +0000 Subject: [PATCH 3/5] Add CrossSocket patches --- Net/Net.CrossSslSocket.Base.pas | 75 +++++++++++++++++++++++++++++++++ Utils/Utils.SyncObjs.pas | 6 ++- boss.json | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Net/Net.CrossSslSocket.Base.pas b/Net/Net.CrossSslSocket.Base.pas index 0b1c52f..22187f5 100644 --- a/Net/Net.CrossSslSocket.Base.pas +++ b/Net/Net.CrossSslSocket.Base.pas @@ -105,6 +105,44 @@ interface /// procedure SetPrivateKeyFile(const APKeyFile: string); + // ── mTLS (mutual TLS / client-certificate authentication) ──────────────── + // [MTLS-1] Load the CA certificate used to verify client certificates. + // Call before Listen/Start. Required when VerifyPeer = True. + // The concrete implementation (TCrossOpenSslSocket) calls + // SSL_CTX_add_client_CA + X509_STORE_add_cert on its private FContext. + + /// + /// 从内存加载CA证书 (mTLS: 客户端证书验证) + /// + procedure SetCACertificate(const ACACertBuf: Pointer; + const ACACertBufSize: Integer); overload; + + /// + /// 从字节数组加载CA证书 + /// + procedure SetCACertificate(const ACACertBytes: TBytes); overload; + + /// + /// 从字符串加载CA证书 + /// + procedure SetCACertificate(const ACACertStr: string); overload; + + /// + /// 从文件加载CA证书 + /// + procedure SetCACertificateFile(const ACACertFile: string); + + // [MTLS-2] Enable or disable client-certificate verification. + // SSL_VERIFY_NONE (False) = server-only TLS — no client cert required. + // SSL_VERIFY_PEER (True) = server requests client cert. + // Combined with SSL_VERIFY_FAIL_IF_NO_PEER_CERT so that a missing or + // invalid certificate aborts the handshake rather than continuing. + + /// + /// 启用/禁用客户端证书验证 (mTLS) + /// + procedure SetVerifyPeer(const AVerify: Boolean); + /// /// 是否已启用 SSL /// @@ -140,6 +178,24 @@ TCrossSslSocketBase = class(TCrossSocket, ICrossSslSocket) procedure SetPrivateKey(const APKeyStr: string); overload; virtual; procedure SetPrivateKeyFile(const APKeyFile: string); virtual; + // ── mTLS ───────────────────────────────────────────────────────────────── + // [MTLS-1] SetCACertificate — abstract; implemented by TCrossOpenSslSocket. + // Calls SSL_CTX_add_client_CA(FContext, LCACert) to add the CA to the + // list of acceptable client CAs sent in the TLS handshake, and + // X509_STORE_add_cert(SSL_CTX_get_cert_store(FContext), LCACert) so + // OpenSSL can verify the client certificate against the CA chain. + procedure SetCACertificate(const ACACertBuf: Pointer; + const ACACertBufSize: Integer); overload; virtual; abstract; + procedure SetCACertificate(const ACACertBytes: TBytes); overload; virtual; + procedure SetCACertificate(const ACACertStr: string); overload; virtual; + procedure SetCACertificateFile(const ACACertFile: string); virtual; + + // [MTLS-2] SetVerifyPeer — abstract; implemented by TCrossOpenSslSocket. + // AVerify = True → SSL_CTX_set_verify(FContext, + // SSL_VERIFY_PEER or SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nil) + // AVerify = False → SSL_CTX_set_verify(FContext, SSL_VERIFY_NONE, nil) + procedure SetVerifyPeer(const AVerify: Boolean); virtual; abstract; + property Ssl: Boolean read GetSsl; end; @@ -190,6 +246,25 @@ procedure TCrossSslSocketBase.SetPrivateKeyFile(const APKeyFile: string); SetPrivateKey(TFileUtils.ReadAllBytes(APKeyFile)); end; +// ── mTLS convenience overloads ──────────────────────────────────────────────── +// These follow the same pattern as SetCertificate/SetPrivateKey: +// convert to bytes/pointer and delegate to the abstract primitive. + +procedure TCrossSslSocketBase.SetCACertificate(const ACACertBytes: TBytes); +begin + SetCACertificate(Pointer(ACACertBytes), Length(ACACertBytes)); +end; + +procedure TCrossSslSocketBase.SetCACertificate(const ACACertStr: string); +begin + SetCACertificate(TEncoding.ANSI.GetBytes(ACACertStr)); +end; + +procedure TCrossSslSocketBase.SetCACertificateFile(const ACACertFile: string); +begin + SetCACertificate(TFileUtils.ReadAllBytes(ACACertFile)); +end; + { TCrossSslConnectionBase } function TCrossSslConnectionBase.GetSsl: Boolean; diff --git a/Utils/Utils.SyncObjs.pas b/Utils/Utils.SyncObjs.pas index c3ff1a0..3a6ad48 100644 --- a/Utils/Utils.SyncObjs.pas +++ b/Utils/Utils.SyncObjs.pas @@ -866,7 +866,11 @@ function TSpinEvent.WaitFor(const ATimeout: Cardinal): TWaitResult; LSpinCount: Integer; LState: Integer; begin +{$IF CompilerVersion >= 35.0} LStartTick := TThread.GetTickCount64; +{$ELSE} + LStartTick := GetTickCount64; +{$IFEND} LSpinCount := 0; while True do @@ -890,7 +894,7 @@ function TSpinEvent.WaitFor(const ATimeout: Cardinal): TWaitResult; // 超时检查移到前面,避免不必要的Sleep if (ATimeout <> INFINITE) then begin - if (TThread.GetTickCount64 - LStartTick >= ATimeout) then + if ({$IF CompilerVersion >= 35.0}TThread.GetTickCount64{$ELSE}GetTickCount64{$IFEND} - LStartTick >= ATimeout) then Exit(TWaitResult.wrTimeout); end; diff --git a/boss.json b/boss.json index 3afba61..52ec717 100644 --- a/boss.json +++ b/boss.json @@ -5,7 +5,7 @@ "homepage": "https://github.com/freitasjca/Delphi-Cross-Socket", "license": "MIT", "mainsrc": "Net/", - "browsingpath": "Net/;Utils/", + "browsingpath": "Net/;Utils/;DelphiToFPC;CnPack/Common/;CnPack/Crypto", "projects": [], "dependencies": {} } \ No newline at end of file From cd7b46319e0a8653a85a9becac7a18076c183859 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Fri, 13 Mar 2026 19:46:49 +0000 Subject: [PATCH 4/5] Add dependent CnPack files --- CnPack/Common/CnPack.inc | 3623 ++++++++++++++++ CnPack/Crypto/CnAES.dcu | Bin 0 -> 122925 bytes CnPack/Crypto/CnAES.pas | 7569 ++++++++++++++++++++++++++++++++++ CnPack/Crypto/CnBase64.dcu | Bin 0 -> 7426 bytes CnPack/Crypto/CnBase64.pas | 547 +++ CnPack/Crypto/CnConsts.dcu | Bin 0 -> 14305 bytes CnPack/Crypto/CnConsts.pas | 250 ++ CnPack/Crypto/CnDES.dcu | Bin 0 -> 30941 bytes CnPack/Crypto/CnDES.pas | 1973 +++++++++ CnPack/Crypto/CnFloat.dcu | Bin 0 -> 15913 bytes CnPack/Crypto/CnFloat.pas | 1354 ++++++ CnPack/Crypto/CnKDF.dcu | Bin 0 -> 13854 bytes CnPack/Crypto/CnKDF.pas | 807 ++++ CnPack/Crypto/CnMD5.dcu | Bin 0 -> 15598 bytes CnPack/Crypto/CnMD5.pas | 884 ++++ CnPack/Crypto/CnNative.dcu | Bin 0 -> 48972 bytes CnPack/Crypto/CnNative.pas | 4904 ++++++++++++++++++++++ CnPack/Crypto/CnPemUtils.dcu | Bin 0 -> 16968 bytes CnPack/Crypto/CnPemUtils.pas | 1219 ++++++ CnPack/Crypto/CnRandom.dcu | Bin 0 -> 5673 bytes CnPack/Crypto/CnRandom.pas | 415 ++ CnPack/Crypto/CnSHA1.dcu | Bin 0 -> 10859 bytes CnPack/Crypto/CnSHA1.pas | 737 ++++ CnPack/Crypto/CnSHA2.dcu | Bin 0 -> 30907 bytes CnPack/Crypto/CnSHA2.pas | 2337 +++++++++++ CnPack/Crypto/CnSHA3.dcu | Bin 0 -> 31943 bytes CnPack/Crypto/CnSHA3.pas | 2700 ++++++++++++ CnPack/Crypto/CnSM3.dcu | Bin 0 -> 14942 bytes CnPack/Crypto/CnSM3.pas | 829 ++++ 29 files changed, 30148 insertions(+) create mode 100644 CnPack/Common/CnPack.inc create mode 100644 CnPack/Crypto/CnAES.dcu create mode 100644 CnPack/Crypto/CnAES.pas create mode 100644 CnPack/Crypto/CnBase64.dcu create mode 100644 CnPack/Crypto/CnBase64.pas create mode 100644 CnPack/Crypto/CnConsts.dcu create mode 100644 CnPack/Crypto/CnConsts.pas create mode 100644 CnPack/Crypto/CnDES.dcu create mode 100644 CnPack/Crypto/CnDES.pas create mode 100644 CnPack/Crypto/CnFloat.dcu create mode 100644 CnPack/Crypto/CnFloat.pas create mode 100644 CnPack/Crypto/CnKDF.dcu create mode 100644 CnPack/Crypto/CnKDF.pas create mode 100644 CnPack/Crypto/CnMD5.dcu create mode 100644 CnPack/Crypto/CnMD5.pas create mode 100644 CnPack/Crypto/CnNative.dcu create mode 100644 CnPack/Crypto/CnNative.pas create mode 100644 CnPack/Crypto/CnPemUtils.dcu create mode 100644 CnPack/Crypto/CnPemUtils.pas create mode 100644 CnPack/Crypto/CnRandom.dcu create mode 100644 CnPack/Crypto/CnRandom.pas create mode 100644 CnPack/Crypto/CnSHA1.dcu create mode 100644 CnPack/Crypto/CnSHA1.pas create mode 100644 CnPack/Crypto/CnSHA2.dcu create mode 100644 CnPack/Crypto/CnSHA2.pas create mode 100644 CnPack/Crypto/CnSHA3.dcu create mode 100644 CnPack/Crypto/CnSHA3.pas create mode 100644 CnPack/Crypto/CnSM3.dcu create mode 100644 CnPack/Crypto/CnSM3.pas diff --git a/CnPack/Common/CnPack.inc b/CnPack/Common/CnPack.inc new file mode 100644 index 0000000..cad0164 --- /dev/null +++ b/CnPack/Common/CnPack.inc @@ -0,0 +1,3623 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{******************************************************************************} +{ } +{ עõԪΪָͱ汾Ϣļ } +{ õԪݲֲο JCL GExperts } +{ } +{******************************************************************************} + +//============================================================================== +// ѡ +//============================================================================== + +{$IFDEF FPC} + // Free Pascal Compiler 3.x Up Definitions + {$DEFINE SUPPORT_PASCAL} // Pascal + {$DEFINE SUPPORT_UINT64} // UInt64 + {$DEFINE SUPPORT_32_AND_64} // ֧ 32 64 λ NativeInt + {$DEFINE SUPPORT_ENCODING} // Unicode ַ֧ Encoding ת + {$DEFINE SUPPORT_INLINE} // ֧ inline + + {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString + {$DEFINE TBYTES_DEFINED} + + // CPU FPC ӳ䵽 Delphi + {$IFDEF CPU386} // Intel 32 CPU + {$DEFINE CPU32BITS} + {$DEFINE CPUX86} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUi386} + {$DEFINE CPU32BITS} + {$DEFINE CPUX86} + {$asmMode intel} + {$ENDIF} + + {$IFDEF CPUAMD64} // Intel 64 CPU + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUX86_64} + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + {$IFDEF CPUIA64} + {$DEFINE CPU64BITS} + {$DEFINE CPUX64} + {$asmMode intel} + {$ENDIF} + + {$IFDEF CPUARM} // ARM 32 bit processor + {$DEFINE CPU32BITS} + {$DEFINE CPUARM} + {$DEFINE CPUARM32} + {$ENDIF} + + {$IFDEF CPUAARCH64} // ARM 64 bit processor + {$DEFINE CPU64BITS} + {$DEFINE CPUARM} + {$DEFINE CPUARM64} + {$ENDIF} + + {$mode Delphi} // Delphi Compatibility, not DelphiUnicodeעԴظ + + // ر Range Check Overflow Check + {$R- No Range checking} + {$OVERFLOWCHECKS OFF} + +{$ELSE FPC} // Below is for Delphi Compiler + +//{$DEFINE PERSONAL_EDITION} +{$DEFINE ENTERPRISE_EDITION} + +{$IFNDEF PERSONAL_EDITION} + {$DEFINE SUPPORT_DB} + {$DEFINE SUPPORT_ADO} +{$ENDIF} + +//============================================================================== +// 汾Ϣ +//============================================================================== + +{$IFDEF VER360} + {$DEFINE COMPILER29} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI29} + {$DEFINE DELPHI120_ATHENS} + {$DEFINE BCB28} + {$DEFINE BCB120_ATHENS} + {$DEFINE BDS23} +{$ENDIF} + +{$IFDEF VER350} + {$DEFINE COMPILER28} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI28} + {$DEFINE DELPHI110_ALEXANDRIA} + {$DEFINE BCB28} + {$DEFINE BCB110_ALEXANDRIA} + {$DEFINE BDS22} +{$ENDIF} + +{$IFDEF VER340} + {$DEFINE COMPILER27} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI27} + {$DEFINE DELPHI104_SYDNEY} + {$DEFINE BCB27} + {$DEFINE BCB104_SYDNEY} + {$DEFINE BDS21} +{$ENDIF} + +{$IFDEF VER330} + {$DEFINE COMPILER26} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI26} + {$DEFINE DELPHI103_RIO} + {$DEFINE BCB26} + {$DEFINE BCB103_RIO} + {$DEFINE BDS20} +{$ENDIF} + +{$IFDEF VER320} + {$DEFINE COMPILER25} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI25} + {$DEFINE DELPHI102_TOKYO} + {$DEFINE BCB25} + {$DEFINE BCB102_TOKYO} + {$DEFINE BDS19} +{$ENDIF} + +{$IFDEF VER310} + {$DEFINE COMPILER24} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI24} + {$DEFINE DELPHI101_BERLIN} + {$DEFINE BCB24} + {$DEFINE BCB101_BERLIN} + {$DEFINE BDS18} +{$ENDIF} + +{$IFDEF VER300} + {$DEFINE COMPILER23} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI23} + {$DEFINE DELPHI10_SEATTLE} + {$DEFINE BCB23} + {$DEFINE BCB10_SEATTLE} + {$DEFINE BDS17} +{$ENDIF} + +{$IFDEF VER290} + {$DEFINE COMPILER22} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI22} + {$DEFINE DELPHIXE8} + {$DEFINE BCB22} + {$DEFINE BCBXE8} + {$DEFINE BDS16} +{$ENDIF} + +{$IFDEF VER280} + {$DEFINE COMPILER21} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI21} + {$DEFINE DELPHIXE7} + {$DEFINE BCB21} + {$DEFINE BCBXE7} + {$DEFINE BDS15} +{$ENDIF} + +{$IFDEF VER270} + {$DEFINE COMPILER20} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI20} + {$DEFINE DELPHIXE6} + {$DEFINE BCB20} + {$DEFINE BCBXE6} + {$DEFINE BDS14} +{$ENDIF} + +{$IFDEF VER260} + {$DEFINE COMPILER19} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI19} + {$DEFINE DELPHIXE5} + {$DEFINE BCB19} + {$DEFINE BCBXE5} + {$DEFINE BDS12} +{$ENDIF} + +{$IFDEF VER250} + {$DEFINE COMPILER18} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI18} + {$DEFINE DELPHIXE4} + {$DEFINE BCB18} + {$DEFINE BCBXE4} + {$DEFINE BDS11} +{$ENDIF} + +{$IFDEF VER240} + {$DEFINE COMPILER17} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI17} + {$DEFINE DELPHIXE3} + {$DEFINE DELPHI2013} + {$DEFINE BCB17} + {$DEFINE BCBXE3} + {$DEFINE BCB2013} + {$DEFINE BDS10} + {$DEFINE BDS2013} +{$ENDIF} + +{$IFDEF VER230} + {$DEFINE COMPILER16} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI16} + {$DEFINE DELPHIXE2} + {$DEFINE DELPHI2012} + {$DEFINE BCB16} + {$DEFINE BCBXE2} + {$DEFINE BCB2012} + {$DEFINE BDS9} + {$DEFINE BDS2012} +{$ENDIF} + +{$IFDEF VER220} + {$DEFINE COMPILER15} + {$IFDEF LINUX} + {$DEFINE UCL10} + {$ELSE} + {$DEFINE VCL71} + {$ENDIF} + {$DEFINE DELPHI15} + {$DEFINE DELPHIXE} + {$DEFINE DELPHI2011} + {$DEFINE BCB15} + {$DEFINE BCBXE} + {$DEFINE BCB2011} + {$DEFINE BDS8} + {$DEFINE BDS2011} +{$ENDIF} + +{$IFDEF VER210} + {$DEFINE COMPILER14} + {$DEFINE VCL71} + {$DEFINE DELPHI14} + {$DEFINE DELPHI2010} + {$DEFINE BCB14} + {$DEFINE BCB2010} + {$DEFINE BDS7} + {$DEFINE BDS2010} +{$ENDIF} + +{$IFDEF VER200} + {$DEFINE COMPILER12} + {$DEFINE VCL71} + {$DEFINE DELPHI12} + {$DEFINE DELPHI2009} + {$DEFINE BCB12} + {$DEFINE BCB2009} + {$DEFINE BDS6} + {$DEFINE BDS2009} +{$ENDIF} + +{$IFDEF VER185} + {$DEFINE COMPILER11} + {$DEFINE VCL71} + {$DEFINE DELPHI11} + {$DEFINE DELPHI2007} + {$DEFINE BCB11} + {$DEFINE BCB2007} + {$DEFINE BDS5} + {$DEFINE BDS2007} + {$UNDEF VER180} +{$ENDIF} + +{$IFDEF VER180} + {$DEFINE COMPILER10} + {$DEFINE VCL71} + {$DEFINE DELPHI10} + {$DEFINE DELPHI2006} + {$DEFINE BCB10} + {$DEFINE BCB2006} + {$DEFINE BDS4} + {$DEFINE BDS2006} +{$ENDIF} + +{$IFDEF VER170} + {$DEFINE COMPILER9} + {$DEFINE VCL71} + {$DEFINE DELPHI9} + {$DEFINE DELPHI2005} + {$DEFINE BDS3} + {$DEFINE BDS2005} +{$ENDIF} + +{$IFDEF VER160} + {$DEFINE COMPILER8} + {$DEFINE VCL71} + {$DEFINE DELPHI8} + {$DEFINE BDS2} +{$ENDIF} + +{$IFDEF VER150} + {$DEFINE COMPILER7} + {$IFDEF LINUX} + {$DEFINE CLX10} + {$ELSE} + {$DEFINE VCL70} + {$DEFINE CLX10} + {$IFDEF BCB} + {$DEFINE BCB7} + {$ELSE} + {$DEFINE DELPHI7} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER140} + {$DEFINE COMPILER6} + {$IFDEF LINUX} + {$DEFINE CLX10} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IFDEF CompilerVersion} + {$IF System.RTLVersion = 14.1} + {$DEFINE KYLIX2} + {$IFEND} + {$IF System.RTLVersion = 14.5} + {$DEFINE KYLIX3} + {$IFEND} + {$ELSE} + {$DEFINE KYLIX1} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$DEFINE VCL60} + {$DEFINE CLX10} + {$IFDEF BCB} + {$DEFINE BCB6} + {$ELSE} + {$DEFINE DELPHI6} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER130} + {$DEFINE COMPILER5} + {$DEFINE VCL50} + {$IFDEF BCB} + {$DEFINE BCB5} + {$ELSE} + {$DEFINE DELPHI5} + {$ENDIF} +{$ENDIF} + +{$IFDEF VER125} + {$DEFINE COMPILER4} + {$DEFINE VCL40} + {$DEFINE BCB4} +{$ENDIF} + +{$IFDEF VER120} + {$DEFINE COMPILER4} + {$DEFINE VCL40} + {$DEFINE DELPHI4} +{$ENDIF} + +{$IFDEF VER110} + {$DEFINE COMPILER35} + {$DEFINE VCL30} + {$DEFINE BCB3} +{$ENDIF} + +{$IFDEF VER100} + {$DEFINE COMPILER3} + {$DEFINE VCL30} + {$DEFINE DELPHI3} +{$ENDIF} + +{$IFDEF VER93} + {$DEFINE COMPILER2} + {$DEFINE VCL20} + {$DEFINE BCB1} +{$ENDIF} + +{$IFDEF VER90} + {$DEFINE COMPILER2} + {$DEFINE VCL20} + {$DEFINE DELPHI2} +{$ENDIF} + +{$IFDEF VER80} + {$DEFINE COMPILER1} + {$DEFINE VCL10} + {$DEFINE DELPHI1} +{$ENDIF} + +// DELPHIX_UP from DELPHIX mappings + +{$IFDEF DELPHI29} + {$DEFINE DELPHI} + {$DEFINE DELPHI29_UP} + {$DEFINE DELPHI28_UP} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI120_ATHENS} + {$DEFINE DELPHI120_ATHENS_UP} + {$DEFINE DELPHI110_ALEXANDRIA_UP} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI28} + {$DEFINE DELPHI} + {$DEFINE DELPHI28_UP} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI110_ALEXANDRIA} + {$DEFINE DELPHI110_ALEXANDRIA_UP} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI27} + {$DEFINE DELPHI} + {$DEFINE DELPHI27_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI104_SYDNEY} + {$DEFINE DELPHI104_SYDNEY_UP} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI26} + {$DEFINE DELPHI} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI103_RIO} + {$DEFINE DELPHI103_RIO_UP} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI25} + {$DEFINE DELPHI} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI102_TOKYO} + {$DEFINE DELPHI102_TOKYO_UP} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI24} + {$DEFINE DELPHI} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI101_BERLIN} + {$DEFINE DELPHI101_BERLIN_UP} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI23} + {$DEFINE DELPHI} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI10_SEATTLE} + {$DEFINE DELPHI10_SEATTLE_UP} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI22} + {$DEFINE DELPHI} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE8} + {$DEFINE DELPHIXE8_UP} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI21} + {$DEFINE DELPHI} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE7} + {$DEFINE DELPHIXE7_UP} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI20} + {$DEFINE DELPHI} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE6} + {$DEFINE DELPHIXE6_UP} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI19} + {$DEFINE DELPHI} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE5} + {$DEFINE DELPHIXE5_UP} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI18} + {$DEFINE DELPHI} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE4} + {$DEFINE DELPHIXE4_UP} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} + + // NO DELPHI2014 defined, so need define below here. + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI17} + {$DEFINE DELPHI} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE3} + {$DEFINE DELPHIXE3_UP} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2013} + {$DEFINE DELPHI2013_UP} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI16} + {$DEFINE DELPHI} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE2} + {$DEFINE DELPHIXE2_UP} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2012} + {$DEFINE DELPHI2012_UP} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI15} + {$DEFINE DELPHI} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHIXE} + {$DEFINE DELPHIXE_UP} +{$ENDIF} + +{$IFDEF DELPHI2011} + {$DEFINE DELPHI2011_UP} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI14} + {$DEFINE DELPHI} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2010} + {$DEFINE DELPHI2010_UP} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI12} + {$DEFINE DELPHI} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2009} + {$DEFINE DELPHI2009_UP} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI11} + {$DEFINE DELPHI} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2007} + {$DEFINE DELPHI2007_UP} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI10} + {$DEFINE DELPHI} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2006} + {$DEFINE DELPHI2006_UP} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI9} + {$DEFINE DELPHI} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2005} + {$DEFINE DELPHI2005_UP} +{$ENDIF} + +{$IFDEF DELPHI8} + {$DEFINE DELPHI} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI7} + {$DEFINE DELPHI} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI4} + {$DEFINE DELPHI} + {$DEFINE DELPHI4_UP} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI3} + {$DEFINE DELPHI} + {$DEFINE DELPHI3_UP} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI2} + {$DEFINE DELPHI} + {$DEFINE DELPHI2_UP} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +{$IFDEF DELPHI1} + {$DEFINE DELPHI} + {$DEFINE DELPHI1_UP} +{$ENDIF} + +// BCBX_UP from BCBX mappings + +{$IFDEF BCB29} + {$DEFINE BCB} + {$DEFINE BCB29_UP} + {$DEFINE BCB28_UP} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB120_ATHENS} + {$DEFINE BCB120_ATHENS_UP} + {$DEFINE BCB110_ALEXANDRIA_UP} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB28} + {$DEFINE BCB} + {$DEFINE BCB28_UP} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB110_ALEXANDRIA} + {$DEFINE BCB110_ALEXANDRIA_UP} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB27} + {$DEFINE BCB} + {$DEFINE BCB27_UP} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB104_SYDNEY} + {$DEFINE BCB104_SYDNEY_UP} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB26} + {$DEFINE BCB} + {$DEFINE BCB26_UP} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB103_RIO} + {$DEFINE BCB103_RIO_UP} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB25} + {$DEFINE BCB} + {$DEFINE BCB25_UP} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB102_TOKYO} + {$DEFINE BCB102_TOKYO_UP} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + + +{$IFDEF BCB24} + {$DEFINE BCB} + {$DEFINE BCB24_UP} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB101_BERLIN} + {$DEFINE BCB101_BERLIN_UP} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB23} + {$DEFINE BCB} + {$DEFINE BCB23_UP} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB10_SEATTLE} + {$DEFINE BCB10_SEATTLE_UP} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB22} + {$DEFINE BCB} + {$DEFINE BCB22_UP} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE8} + {$DEFINE BCBXE8_UP} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB21} + {$DEFINE BCB} + {$DEFINE BCB21_UP} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE7} + {$DEFINE BCBXE7_UP} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB20} + {$DEFINE BCB} + {$DEFINE BCB20_UP} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE6} + {$DEFINE BCBXE6_UP} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB19} + {$DEFINE BCB} + {$DEFINE BCB19_UP} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE5} + {$DEFINE BCBXE5_UP} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB18} + {$DEFINE BCB} + {$DEFINE BCB18_UP} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE4} + {$DEFINE BCBXE4_UP} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} + + // NO BCB2014 defined, so need define below here. + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB17} + {$DEFINE BCB} + {$DEFINE BCB17_UP} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE3} + {$DEFINE BCBXE3_UP} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2013} + {$DEFINE BCB2013_UP} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB16} + {$DEFINE BCB} + {$DEFINE BCB16_UP} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE2} + {$DEFINE BCBXE2_UP} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2012} + {$DEFINE BCB2012_UP} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB15} + {$DEFINE BCB} + {$DEFINE BCB15_UP} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCBXE} + {$DEFINE BCBXE_UP} +{$ENDIF} + +{$IFDEF BCB2011} + {$DEFINE BCB2011_UP} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB14} + {$DEFINE BCB} + {$DEFINE BCB14_UP} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2010} + {$DEFINE BCB2010_UP} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB12} + {$DEFINE BCB} + {$DEFINE BCB12_UP} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2009} + {$DEFINE BCB2009_UP} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB11} + {$DEFINE BCB} + {$DEFINE BCB11_UP} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2007} + {$DEFINE BCB2007_UP} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB10} + {$DEFINE BCB} + {$DEFINE BCB10_UP} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB2006} + {$DEFINE BCB2006_UP} +{$ENDIF} + +{$IFDEF BCB7} + {$DEFINE BCB} + {$DEFINE BCB7_UP} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB6} + {$DEFINE BCB} + {$DEFINE BCB6_UP} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB5} + {$DEFINE BCB} + {$DEFINE BCB5_UP} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB4} + {$DEFINE BCB} + {$DEFINE BCB4_UP} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB3} + {$DEFINE BCB} + {$DEFINE BCB3_UP} + {$DEFINE BCB1_UP} +{$ENDIF} + +{$IFDEF BCB1} + {$DEFINE BCB} + {$DEFINE BCB1_UP} +{$ENDIF} + +// KYLIXX_UP from KYLIXX mappings + +{$IFDEF KYLIX3} + {$DEFINE KYLIX} + {$DEFINE KYLIX3_UP} + {$DEFINE KYLIX2_UP} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +{$IFDEF KYLIX2} + {$DEFINE KYLIX} + {$DEFINE KYLIX2_UP} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +{$IFDEF KYLIX1} + {$DEFINE KYLIX} + {$DEFINE KYLIX1_UP} +{$ENDIF} + +// BDSXX_UP from BDSXX mappings + +{$IFDEF BDS23} // 12.0 ATHENS + {$DEFINE BDS} + {$DEFINE BDS23_UP} + {$DEFINE BDS22_UP} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS22} // 11.0 ALEXANDRIA + {$DEFINE BDS} + {$DEFINE BDS22_UP} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS21} // 10.4 SYDNEY + {$DEFINE BDS} + {$DEFINE BDS21_UP} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS20} // 10.3 RIO + {$DEFINE BDS} + {$DEFINE BDS20_UP} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS19} // 10.2 Tokyo + {$DEFINE BDS} + {$DEFINE BDS19_UP} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS18} // 10.1 Berlin + {$DEFINE BDS} + {$DEFINE BDS18_UP} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS17} // 10 Seattle + {$DEFINE BDS} + {$DEFINE BDS17_UP} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS16} + {$DEFINE BDS} + {$DEFINE BDS16_UP} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS15} + {$DEFINE BDS} + {$DEFINE BDS15_UP} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS14} + {$DEFINE BDS} + {$DEFINE BDS14_UP} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS12} + {$DEFINE BDS} + {$DEFINE BDS12_UP} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS11} + {$DEFINE BDS} + {$DEFINE BDS11_UP} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} + + // NO BDS2014 defined, so need define below here. + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS10} + {$DEFINE BDS} + {$DEFINE BDS10_UP} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2013} + {$DEFINE BDS2013_UP} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS9} + {$DEFINE BDS} + {$DEFINE BDS9_UP} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2012} + {$DEFINE BDS2012_UP} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS8} + {$DEFINE BDS} + {$DEFINE BDS8_UP} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2011} + {$DEFINE BDS2011_UP} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS7} + {$DEFINE BDS} + {$DEFINE BDS7_UP} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2010} + {$DEFINE BDS2010_UP} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS6} + {$DEFINE BDS} + {$DEFINE BDS6_UP} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2009} + {$DEFINE BDS2009_UP} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS5} + {$DEFINE BDS} + {$DEFINE BDS5_UP} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2007} + {$DEFINE BDS2007_UP} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS4} + {$DEFINE BDS} + {$DEFINE BDS4_UP} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2006} + {$DEFINE BDS2006_UP} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS3} + {$DEFINE BDS} + {$DEFINE BDS3_UP} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS2005} + {$DEFINE BDS2005_UP} +{$ENDIF} + +{$IFDEF BDS2} + {$DEFINE BDS} + {$DEFINE BDS2_UP} + {$DEFINE BDS1_UP} +{$ENDIF} + +{$IFDEF BDS1} + {$DEFINE BDS} + {$DEFINE BDS1_UP} +{$ENDIF} + +// COMPILERX_UP from COMPILERX mappings + +{$IFDEF COMPILER29} // 12.0 ATHENS + {$DEFINE COMPILER29_UP} + {$DEFINE COMPILER28_UP} + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER28} // 11.0 ALEXANDRIA + {$DEFINE COMPILER28_UP} + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER27} // 10.4 SYDNEY + {$DEFINE COMPILER27_UP} + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER26} // 10.3 RIO + {$DEFINE COMPILER26_UP} + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER25} // 10.2 Tokyo + {$DEFINE COMPILER25_UP} + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER24} // 10.1 Berlin + {$DEFINE COMPILER24_UP} + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER23} // 10 Seattle + {$DEFINE COMPILER23_UP} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER22} + {$DEFINE COMPILER22_UP} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER21} + {$DEFINE COMPILER21_UP} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER20} + {$DEFINE COMPILER20_UP} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER19} + {$DEFINE COMPILER19_UP} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER18} + {$DEFINE COMPILER18_UP} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER17} + {$DEFINE COMPILER17_UP} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER16} + {$DEFINE COMPILER16_UP} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER15} + {$DEFINE COMPILER15_UP} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER14} + {$DEFINE COMPILER14_UP} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER12} + {$DEFINE COMPILER12_UP} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER11} + {$DEFINE COMPILER11_UP} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER10} + {$DEFINE COMPILER10_UP} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER9} + {$DEFINE COMPILER9_UP} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER8} + {$DEFINE COMPILER8_UP} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER7} + {$DEFINE COMPILER7_UP} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER6} + {$DEFINE COMPILER6_UP} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER5} + {$DEFINE COMPILER5_UP} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER4} + {$DEFINE COMPILER4_UP} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER35} + {$DEFINE COMPILER35_UP} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER3} + {$DEFINE COMPILER3_UP} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER2} + {$DEFINE COMPILER2_UP} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +{$IFDEF COMPILER1} + {$DEFINE COMPILER1_UP} +{$ENDIF} + +// VCLXX_UP from VCLXX mappings + +{$IFDEF UCL10} + {$DEFINE UCL10_UP} +{$ENDIF} + +{$IFDEF VCL71} + {$DEFINE VCL71_UP} + {$DEFINE VCL70_UP} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL70} + {$DEFINE VCL70_UP} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL60} + {$DEFINE VCL60_UP} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL50} + {$DEFINE VCL50_UP} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL40} + {$DEFINE VCL40_UP} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL30} + {$DEFINE VCL30_UP} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL20} + {$DEFINE VCL20_UP} + {$DEFINE VCL10_UP} +{$ENDIF} + +{$IFDEF VCL10} + {$DEFINE VCL10_UP} +{$ENDIF} + +// CLXXX_UP from CLXXX mappings + +{$IFDEF CLX10} + {$DEFINE CLX10_UP} +{$ENDIF} + +//============================================================================== +// ƽ̨ض +//============================================================================== + +{$IFDEF COMPILER1} + {$DEFINE WIN16} + {$DEFINE MSWINDOWS} +{$ENDIF} + +{$IFDEF BDS} + {$DEFINE DOTNET} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE MSWINDOWS} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE UNIX} + {$DEFINE COMPLIB_CLX} +{$ENDIF} + +{$IFNDEF COMPLIB_CLX} + {$DEFINE COMPLIB_VCL} +{$ENDIF} + +//============================================================================== +// ӳ汾ϢѺõָ +//============================================================================== + +{$IFDEF DELPHI} + {$DEFINE SUPPORT_PASCAL} +{$ENDIF} + +{$IFDEF BCB} + {$DEFINE SUPPORT_PASCAL} + {$DEFINE SUPPORT_CPLUSPLUS} +{$ENDIF} + +{$IFDEF DELPHI120_ATHENS_UP} + {$DEFINE LIST_INDEX_NATIVEINT} // Athens 12 TList use NativeInt for Index and Count instead of Integer + {$DEFINE IDE_HAS_TABMENU_COPY_PATH} // Athens 12 editor tab menu has item to copy path or filename + {$DEFINE IDE_HAS_DBCLICK_HIGHLIGHT} // Athens 12 editor double click selection highlight + {$DEFINE OTA_CODEEDITOR_SERVICE} // 11.3 ToolsAPI.Editor ӿڣʱ޷ 11.0/1/2 ֻ֣ܼӵ 12 +{$ENDIF} + +{$IFDEF DELPHI110_ALEXANDRIA_UP} + {$DEFINE NO_OLDCREATEORDER} // Alexandria 11 removed OldCreateOrder + {$DEFINE IDE_SUPPORT_HDPI} // Alexandria 11 supports HDPI using TVirtualImageList, etc. + {$DEFINE IDE_HAS_AUTO_READONLY} // Alexandria 11 supports auto open VCL source readonly + {$DEFINE IDE_HAS_MEMORY_VISUALIZAER} // Alexandria 11 has Memory Visualizer for Debug + {$DEFINE TSTRINGS_SETTEXTSTR_CANNULL} // Alexandria 11 TStrings.SetTextStr Ignore #0 Terminated Char + {$DEFINE MEMORYSTREAM_CAPACITY_NATIVEINT} // Alexandria 11 TMemoryStream Capacity is NativeInt instead of Longint +{$ENDIF} + +{$IFDEF DELPHI104_SYDNEY_UP} + {$DEFINE IDE_SUPPORT_LSP} // Sydney 10.4 ֧ LSP Է + {$DEFINE IDE_HAS_ERRORINSIGHT} // Sydney 10.4.2 ֱ֧༭ ErrorInsight + {$DEFINE IDE_EDITOR_CUSTOM_COLUMN} // Sydney 10.4 ϱ༭ Gutter ֧Զ壬ûӿڲݣԼ + {$DEFINE IDE_SWITCH_BUG} // Sydney 10.4.2 ڴļʱĪл̨ Bug +{$ENDIF} + +{$IFDEF DELPHI103_RIO_UP} + {$DEFINE SUPPORT_MACOS64} // Rio 10.3.2 ֧ 64 λ MacOS +{$ENDIF} + +{$IFDEF DELPHI102_TOKYO_UP} + {$DEFINE SUPPORT_LINUX64} // Tokyo 10.2 ֧ Linux 64 λ Server + {$DEFINE IDE_SUPPORT_THEMING} // Tokyo 10.2.2 ֧ IDE л +{$ENDIF} + +{$IFDEF DELPHI101_BERLIN_UP} + {$DEFINE IDE_NEW_EMBEDDED_DESIGNER} // 101B Re-opens "Embedded Designer" Option and Gives a New Container. +{$ENDIF} + +{$IFDEF DELPHI10_SEATTLE_UP} + {$DEFINE IDE_HAS_OWN_STRUCTUAL_HIGHLIGHT} // 10S has own Structual Highlight + {$DEFINE IDE_HAS_HIDE_NONVISUAL} // 10S has "Hide Nonvisual" Feature. +{$ENDIF} + +{$IFDEF DELPHIXE8_UP} + {$DEFINE INIFILE_READWRITE_INTEGER} // XE8 IniFile ReadInteger WriteInteger ʼ LongInt Ϊ Integer + {$DEFINE IDE_INTEGRATE_CASTALIA} // XE8/10S and above integrate Castalia. +{$ENDIF} + +{$IFDEF COMPILER21_UP} // COMPILER21 = XE7 + {$DEFINE NOT_SUPPORT_BDE} // BDE +{$ENDIF} + +{$IFDEF DELPHIXE7_UP} + {$DEFINE SUPPORT_TBYTES_OPERATION} // XE7 TBytes ʼ֧ӡȲ + {$DEFINE FMX_CONTROL_HAS_SIZE} // XE7 FMX Control Size +{$ENDIF} + +{$IFDEF DELPHIXE6_UP} + {$DEFINE SUPPORT_JSON} // XE6 System.JSON ⣬ DBX/REST +{$ENDIF} + +{$IFDEF DELPHIXE5_UP} + {$DEFINE SUPPORT_MOBILE} // XE5 ʼ֧ƶ + {$DEFINE IDE_HAS_INSIGHT} // XE5 has IDE Insight Bar +{$ENDIF} + +{$IFDEF DELPHIXE4_UP} + {$IFNDEF DISABLE_FMX} + {$DEFINE SUPPORT_FMX_FRAME} // XE4 FMX Supports FMX Frame + {$ENDIF} +{$ELSE} + {$DEFINE MEMO_CARETPOS_BUG} // Memo CaretPos Get Negative Error Value for Large File under XE3 or below +{$ENDIF} + +{$IFDEF DELPHIXE3_UP} + {$DEFINE SUPPORT_ATOMIC} // XE3 has Atomic Routines + {$DEFINE TCONTROL_HAS_STYLEELEMENTS} // XE3 TControl has StyleElements Property + {$DEFINE IDE_NP_FMX_DESIGN_BUG} // XE3 FMX Designer Cut/Copy/Paste cause AV Bug for -np switch +{$ENDIF} + +{$IFDEF DELPHIXE2_UP} + {$DEFINE SUPPORT_WIN64} // XE2 Supports Win64 + {$DEFINE SUPPORT_MACOS32} // XE2 Supports MacOS 32 + {$DEFINE SUPPORT_UNITNAME_DOT} + {$DEFINE SUPPORT_ENHANCED_INDEXEDPROPERTY} // XE2 New RTTI Supports IndexedProperty + {$DEFINE SUPPORT_ZLIB_WINDOWBITS} // XE2 ZLib Supports WindowBits + {$DEFINE SUPPORT_GDIPLUS} // XE2 Supports GDI+ + {$DEFINE SUPPORT_INT64ARRAY} // XE2 Defined Int64Array + {$DEFINE SUPPORT_ALPHACOLOR} // XE2 System.UITypes Has TAlphaColors +{$ENDIF} + +{$IFDEF DELPHIXE_UP} + {$DEFINE TSTRINGS_HAS_WRITEBOM} // XE TStrings has WriteBOM property. + {$DEFINE IDE_HAS_DEBUGGERVISUALIZER} // XE ToolsAPI has Debugger Visualizer Interfaces. + {$DEFINE IDE_HAS_STRINGS_VISUALIZAER} // XE has TStrings Visualizer for Debug +{$ENDIF} + +{$IFDEF BDS2012_UP} // 2012 = XE2 + {$DEFINE SUPPORT_32_AND_64} // XE2 Support Win32 and Win64 + {$IFNDEF DISABLE_FMX} + {$DEFINE SUPPORT_FMX} + {$ENDIF} + {$DEFINE SUPPORT_CROSS_PLATFORM} // XE2 ֿ֧ƽ̨ + {$DEFINE VERSIONINFO_PER_CONFIGURATION} // Every Configuruation can have a Version Info. + {$DEFINE OTA_ENVOPTIONS_PLATFORM_BUG} + // A Bug Can't get Correct Env Option Values for Current Platform. + {$DEFINE LIST_NEW_POINTER} +{$ENDIF} + +{$IFDEF BDS2010_UP} + {$DEFINE SUPPORT_INTERFACE_AS_OBJECT} + {$DEFINE SUPPORT_ENHANCED_RTTI} // New enhanced RTTI. + {$DEFINE SUPPORT_EXTERNAL_DELAYED} // External functions can be declared as 'delayed'. + {$DEFINE SUPPORT_CLASS_CONSTRUCTOR} // 2010 and above Supports class constructor and destructor + {$DEFINE SUPPORT_CLASS_DESTRUCTOR} + {$DEFINE IMAGELIST_BEGINENDUPDATE} // 2010 ʼImageList й BeginUpdate EndUpdate + {$DEFINE OTA_DEBUG_HAS_EVENTS} // 2010 µ DebuggerService ProcessDebugEvents + {$DEFINE IDE_HAS_NEW_COMPONENT_PALETTE} // IDE has a new style Component Palette. + {$DEFINE IDE_HAS_EDITOR_SEARCHPANEL} // Editor has a Search Panel + {$DEFINE IDE_HAS_DATETIME_HINT} // TDate/TTime/TDateTime shows Normally in Debug Hint +{$ENDIF} + +{$IFDEF BDS2010} + // 2010 EditView CursorPos EditPosition.InsertText ƫ + {$DEFINE EDITVIEW_SETCURSORPOS_BUG} +{$ENDIF} + +{$IFDEF BDS2009_UP} + {$DEFINE UNICODE_STRING} + {$DEFINE SUPPORT_ATTRIBUTE} // ֧ Attribute + {$DEFINE SUPPORT_GENERIC} // ַ֧ + {$DEFINE SUPPORT_ANSISTRING_CODEPAGE} // AnsiString ָ֧ҳ + {$DEFINE SUPPORT_ENCODING} // Unicode with TEncoding + {$DEFINE SUPPORT_PUINT64} // Has Pointer of UInt64 + {$DEFINE OBJECT_HAS_TOSTRING} // TObject.ToString Function + {$DEFINE OBJECT_HAS_EQUAL} // TObject.Equal Function + {$DEFINE OBJECT_HAS_GETHASHCODE} // TObject.GetHashCode Function + {$DEFINE TGRAPHIC_SUPPORT_PARTIALTRANSPARENCY} // TGraphic ֧ Alpha ͨ͸ + {$DEFINE SUPPORT_OTA_PROJECT_CONFIGURATION} + + {$DEFINE IDE_MAINFORM_EAT_MOUSEWHEEL} + // MainForm of 2009 or Above will eat Message in MouseWheelHandler + {$DEFINE IDE_CODEINSIGHT_AUTOINVOKE} + // IDE Code Insight has Auto Invoke Option + {$DEFINE EDITVIEW_CONVERTPOS_BUG} + // 2009 or Above IEditView.ConvertPos Incorrect when Meeting Unicode Chars. + + {$IFNDEF DELPHIXE2_UP} // 2009/2010/XE has a Project Version Number Bug. + {$DEFINE PROJECT_VERSION_NUMBER_BUG} + {$ENDIF} + {$DEFINE OTA_DPKOPTION_SETVALUE_CORRUPT_BUG} + // A OpenTools API Bug IOTAProjectOptions.SetOptionValue under 2009 or above: + // Set an Option Value to DPK Project Options maybe cause DPK Source Corrupt. +{$ELSE} + {$DEFINE ZLIB_STREAM_NOSIZE} // 2007 µ Zlib Ľѹ֧ Size +{$ENDIF} + +{$IFDEF BDS2009} + // 2009 CreateParams пܵѭ + {$DEFINE CREATE_PARAMS_BUG} + // 2009 EditView CursorPos EditPosition.InsertText ƫ + {$DEFINE EDITVIEW_SETCURSORPOS_BUG} +{$ENDIF} + +{$IFDEF BDS2007_UP} + {$DEFINE IDE_CONF_MANAGER} + {$DEFINE TBYTES_DEFINED} // 2007 Defined TBytes = array of Byte; + {$DEFINE PROJECT_FILENAME_DPROJ} // Project File is .dproj +{$ENDIF} + +{$IFDEF BDS2007} + // RAD Studio 2007 ¿ AutoComplete ᵼĺ˸ + {$DEFINE COMBOBOX_CHS_BUG} +{$ENDIF} + +{$IFDEF BDS2006_UP} + {$DEFINE SUPPORT_CLASS_VAR} // 2006 and above Supports class var + {$DEFINE TCONTROL_HAS_MARGINS} // 2006 and above TControl has Margins + {$DEFINE TCONTROL_HAS_EXPLICIT_BOUNDS} // 2006 and above TControl has Explicit Bounds + {$DEFINE TCONTROL_HAS_MOUSEENTERLEAVE} // 2006 and above TControl has Mouse Enter/Leave Events + {$DEFINE OTA_CODE_TEMPLATE_API} // 2006 and above Provides CodeTemplateAPI. + {$DEFINE OTA_DEBUG_HAS_ERBUSY} // 2006 µ Evaluate зֵ erBusy + {$DEFINE IDE_HAS_GUIDE_LINE} // 2006 and above has Designer Guide Line + {$DEFINE IDE_SYNC_EDIT_BLOCK} // 2006 and above Editor Supports Sync Block Edit + {$DEFINE EDITOR_TAB_ONLYFROM_WINCONTROL} + // From BDS 2006 IDEGraident Editor Tab is Only From WinControl, not TabSet/TabControl +{$ENDIF} + +{$IFDEF BDS2005_UP} + {$DEFINE OTA_PALETTE_API} // 2005 and above Provides PaletteAPI. + {$DEFINE IDE_EDITOR_ELIDE} // 2005 ϱ༭֧۵ + {$DEFINE IDE_FILE_HISTORY} // 2005 ϰ汾洢ļʷ汾 +{$ENDIF} + +{$IFDEF BDS2006} + {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj +{$ENDIF} + +{$IFDEF BDS2005} + {$DEFINE PROJECT_FILENAME_BDSPROJ} // Project File is .bdsproj +{$ENDIF} + +{$IFDEF BDS} // 2005 + {$DEFINE SUPPORT_PASCAL} + {$DEFINE SUPPORT_CSHARP} + {$DEFINE SUPPORT_INLINE} + {$DEFINE SUPPORT_UINT64} + {$DEFINE IDE_WIDECONTROL} // 2005 ϵı༭ڲǿַ UTF-8Ƿ Unicode + {$DEFINE IDE_EDITOR_SUPPORT_FOLDING} // 2005 ϵı༭֧۵ + {$DEFINE OTA_NEW_BREAKPOINT_NOBUG} // 2005 ϵ NewBreakpoint ܹ + {$DEFINE IDE_ACTION_UPDATE_DELAY} // IDE's Action Menu Update will Delay in 2005 or Up. + {$DEFINE SUPPORT_WIDECHAR_IDENTIFIER} + + {$IFNDEF COMPILER12_UP} + // 2005~2007 Compiler is Ansi but Editor String is UTF-8 + {$DEFINE IDE_STRING_ANSI_UTF8} + {$ENDIF} +{$ENDIF} + +{$IFDEF DELPHI7_UP} + {$DEFINE SUPPORT_FORMAT_SETTINGS} // Delphi 7 ʼ֧ FormatSettings + {$DEFINE IDE_MENUBAR_VERTICAL_POSITION_BUG} + // Delphi 7 ϵ MenuBar ֱϵĵλü׳Ͻ + {$DEFINE IDE_MENUBAR_VERTICAL_NOSCROLL_BUG} + // Delphi 7 ϵ MenuBar ֱʱ +{$ENDIF} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORT_DEPRECATED} +{$ENDIF} + +{$IFDEF COMPILER6_UP} + {$DEFINE SUPPORT_ENUMVALUES} + {$DEFINE SUPPORT_VARIANTS} + {$DEFINE SUPPORT_IFDIRECTIVE} +{$ENDIF} + +{$IFDEF DELPHI5_UP} + {$IFNDEF BDS2005_UP} + {$DEFINE PROJECT_FILENAME_DPR} // Delphi 5/6/7 Project File is .dpr + {$ENDIF} +{$ENDIF} + +{$IFDEF COMPILER5} + {$DEFINE TSTREAM_LONGINT} // D6 ϵ TStream Int64 +{$ENDIF} + +{$IFDEF BCB5} + {$DEFINE BCB5OR6} // һ BCB5OR6 Է BCB5 BCB6 ʹ +{$ENDIF} + +{$IFDEF BCB6} + {$DEFINE BCB5OR6} +{$ENDIF} + +{$IFDEF BCB5OR6} + {$DEFINE NO_ZLIB} +{$ENDIF} + +{$IFDEF DELPHI5} + {$DEFINE DELPHI5OR6} // һ DELPHI5OR6 Է DELPHI5 DELPHI6 ʹ +{$ENDIF} + +{$IFDEF DELPHI6} + {$DEFINE DELPHI5OR6} +{$ENDIF} + +{$IFDEF COMPILER4_UP} + {$DEFINE SUPPORT_INT64} + {$DEFINE SUPPORT_DYNAMICARRAYS} + {$DEFINE SUPPORT_DEFAULTPARAMS} + {$DEFINE SUPPORT_REINTRODUCE} + {$DEFINE SUPPORT_OVERLOAD} +{$ENDIF} + +{$IFDEF COMPILER35_UP} + {$DEFINE SUPPORT_EXTSYM} + {$DEFINE SUPPORT_NODEFINE} +{$ENDIF} + +{$IFDEF COMPILER3_UP} + {$DEFINE SUPPORT_WIDESTRING} + {$DEFINE SUPPORT_INTERFACE} +{$ENDIF} + +{$IFDEF WIN64} + {$DEFINE EXTENDED_SIZE_8} // Win64 Extended ͳ 8 ֽ +{$ENDIF} + +{$IFDEF CPUARM} + {$DEFINE EXTENDED_SIZE_8} // ARM ƽ̨ Extended ͳ 8 ֽ +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE EXTENDED_SIZE_10} // Win32 Extended ͳ 10 ֽ +{$ENDIF} + +{$IFDEF MACOS64} + {$DEFINE EXTENDED_SIZE_16} // MacOS64 Extended ͳ 16 ֽ +{$ENDIF} + +{$IFDEF LINUX64} + {$DEFINE EXTENDED_SIZE_16} // Linux64 Extended ͳ 16 ֽ +{$ENDIF} + +//============================================================================== +// PascalScript ĵ +//============================================================================== + +{.$DEFINE ALLDEBUG} // òƲҪȽ + +//============================================================================== +// ֶ +//============================================================================== + +{$DEFINE GB2312} +{.$DEFINE BIG5} +{.$DEFINE ENGLISH} + +//============================================================================== +// ıָ +//============================================================================== + +{$A+ Force alignment on word/dword boundaries} +{$S+ stack checking} + +{$B- Short evaluation of boolean values} +{$H+ Long string support} +{$V- No var string checking} +{$X+ Extended syntax} +{$P+ Open string parameters} +{$J+ Writeable typed constants} +{$R- No Range checking} +{$OVERFLOWCHECKS OFF} + +{$IFDEF COMPILER6_UP} + {$WARN SYMBOL_PLATFORM OFF} + {$WARN UNIT_PLATFORM OFF} + {$WARN SYMBOL_DEPRECATED OFF} + {$WARN UNIT_DEPRECATED OFF} +{$ENDIF} + +{$IFDEF COMPILER7_UP} + {$WARN UNSAFE_CAST OFF} + {$WARN UNSAFE_CODE OFF} + {$WARN UNSAFE_TYPE OFF} +{$ENDIF} + +{$IFDEF BCB} + {$OBJEXPORTALL ON} +{$ENDIF} + +{$DEFINE CN_USE_MSXML} + +{$ENDIF FPC} + diff --git a/CnPack/Crypto/CnAES.dcu b/CnPack/Crypto/CnAES.dcu new file mode 100644 index 0000000000000000000000000000000000000000..ebc666a410074a233b156bd06d693c171451fb02 GIT binary patch literal 122925 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 +================================================================================ +* ƣ +* ԪƣAES ԳƼӽ㷨ʵֵԪ +* ԪߣCnPack (master@cnpack.org) +* EldoS, Alexander Ionov ĵԪֲ书ܣԭаȨϢ +* עԪʵ AES 128/192/256 ԳƼӽ㷨ֿС̶ 16 ֽڣģʽ +* Ķ뷽ʽĩβ 0Ԫڲ֧ PKCS ȿ뷽ʽҪⲿ +* CnPemUtils.pas Ԫе PKCS ϵкԼӽݽж⴦ +* +* ߰汾 Delphi 뾡ʹ AnsiString 汾ĺʮƳ⣩ +* ⲻַӰӽܽ +* +* 䣺============= Java Ĭϵ AES Ӧ˴ AES256 ============ +* ⣬C++Builder 5/6 ¶ overload ĺʴжϴӶ +* ҵΣʱԪ˴ overload Delphi ´ڣ +* ٷװ˲ֲͬĺ֧ C++Builder 5/6 ±С +* +* ECB/CBC ǿģʽҪ롣CFB/OFB/CTR ĵģʽ뵽顣 +* +* ⣬CTR ģʽ RFC 3686 淶紫ݵ 4 ֽ Nonce8 ֽ +* ʼ4 ֽֽļƴ 16 ֽڵijʼ +* AES 㣬ӽܾΪĶ +* +* ƽ̨Delphi5 + Win 7 +* ޸ļ¼2024.07.25 V1.3 +* CTR ģʽ֧֣ѭ RFC 3686 淶 +* 2024.05.26 V1.2 +* 䲿֧ C++Builder ĺ +* 2022.06.21 V1.1 +* 뼸ֽ鵽ʮַ֮ļӽܺ +* 2021.12.11 V1.2 +* CFB/OFB ģʽ֧ +* 2019.04.15 V1.1 +* ֧ Win32/Win64/MacOS +* 2015.01.21 V1.0 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnNative; + +const + CN_AES_BLOCKSIZE = 16; + {* AES ķܿСλ٣Ϊ 16 ֽ} + +type + TCnKeyBitType = (kbt128, kbt192, kbt256); + {* AES λ16 ֽڡ24 ֽں 32 ֽ} + + ECnAESException = class(Exception); + {* AES 쳣} + + TCnAESBuffer = array [0..15] of Byte; + {* AES ӽܿ 16 ֽ} + + TCnAESKey128 = array [0..15] of Byte; + {* AES128 Կṹ16 ֽ} + + TCnAESKey192 = array [0..23] of Byte; + {* AES192 Կṹ24 ֽ} + + TCnAESKey256 = array [0..31] of Byte; + {* AES256 Կṹ32 ֽ} + + TCnAESExpandedKey128 = array [0..43] of Cardinal; + {* AES128 չԿṹ} + + TCnAESExpandedKey192 = array [0..53] of Cardinal; + {* AES192 չԿṹ} + + TCnAESExpandedKey256 = array [0..63] of Cardinal; + {* AES256 չԿṹ} + + PCnAESBuffer = ^TCnAESBuffer; + PCnAESKey128 = ^TCnAESKey128; + PCnAESKey192 = ^TCnAESKey192; + PCnAESKey256 = ^TCnAESKey256; + PCnAESExpandedKey128 = ^TCnAESExpandedKey128; + PCnAESExpandedKey192 = ^TCnAESExpandedKey192; + PCnAESExpandedKey256 = ^TCnAESExpandedKey256; + + TCnAESCTRNonce = array[0..3] of Byte; + {* CTR ģʽµ Nonce ṹ4 ֽ} + TCnAESCTRIv = array[0..7] of Byte; + {* CTR ģʽµijʼṹ8 ֽ} + +// Key Expansion Routines for Encryption + +procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +{* ڼܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +{* ڼܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +{* ڼܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +// Block Encryption Routines ܣInBuf OutBuf ͬһ + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); overload; +{* AES128 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); overload; +{* AES192 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); overload; +{* AES256 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +{* AES128 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +{* AES192 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +{* AES256 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +// Stream Encryption Routines (ECB mode) ECB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); overload; +{* AES128 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; +{* AES128 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; +{* AES192 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; +{* AES256 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +{* AES128 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +{* AES128 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +{* AES192 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +{* AES192 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +{* AES256 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +{* AES256 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CBC mode) CBC + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CFB mode) CFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (OFB mode) OFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - ?? + + ֵޣ +} +procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Encryption Routines (CTR mode) CTR + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Key Transformation Routines for Decryption + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); overload; +{* ڽܳչ AES128 Կ + + + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); overload; +{* ڽܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); overload; +{* ڽܳչ AES192 Կ + + + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); overload; +{* ڽܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); overload; +{* ڽܳչ AES256 Կ + + + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); overload; +{* ڽܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); +{* ڽܳչ AES128 Կ + + + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +{* ڽܳչ AES128 Կ + + + const Key: TCnAESKey128 - չ AES128 Կ + var ExpandedKey: TCnAESExpandedKey128 - չ AES128 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); +{* ڽܳչ AES192 Կ + + + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +{* ڽܳչ AES192 Կ + + + const Key: TCnAESKey192 - չ AES192 Կ + var ExpandedKey: TCnAESExpandedKey192 - չ AES192 չԿ + + ֵޣ +} + +procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); +{* ڽܳչ AES256 Կ + + + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} +procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +{* ڽܳչ AES256 Կ + + + const Key: TCnAESKey256 - չ AES256 Կ + var ExpandedKey: TCnAESExpandedKey256 - չ AES256 չԿ + + ֵޣ +} + +// Block Decryption Routines + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); overload; +{* AES128 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); overload; +{* AES192 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); overload; +{* AES256 ܿ飬 Delphi ¿á + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +{* AES128 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey128 - չ AES128 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +{* AES192 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey192 - չ AES192 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} +procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +{* AES256 ܿ飬InBuf OutBuf ͬһ + + + const InBuf: TCnAESBuffer - ܵݿ + const Key: TCnAESExpandedKey256 - չ AES256 Կ + var OutBuf: TCnAESBuffer - ĵݿ + + ֵޣ +} + +// Stream Decryption Routines (ECB mode) ECB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); overload; +{* AES128 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); overload; +{* AES128 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); overload; +{* AES192 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); overload; +{* AES192 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); overload; +{* AES256 ECB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); overload; +{* AES256 ECB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +{* AES128 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +{* AES128 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +{* AES192 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +{* AES192 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +{* AES256 ECB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +{* AES156 ECB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CBC mode) CBC + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CBC ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CBC ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CBC ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CBC ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CFB mode) CFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 CFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 CFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 CFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 CFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (OFB mode) OFB + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES128 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES128 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES192 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES192 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); overload; +{* AES256 OFB ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); overload; +{* AES256 OFB ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES128 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES128 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES192 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES192 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +{* AES256 OFB ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +{* AES256 OFB ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const InitVector: TCnAESBuffer - 16 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// Stream Decryption Routines (CTR mode) CTR + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES128 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES192 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); overload; +{* AES256 CTR ģʽʹչԿ Delphi ¿á + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +{$ENDIF} + +// Delphi C++Builder ¾ +procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey128 - 16 ֽ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES128 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey128 - չ AES128 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey192 - 24 ֽ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES192 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey192 - չ AES192 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnAESKey256 - 32 ֽ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} +procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +{* AES256 CTR ģʽʹչԿ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const ExpandedKey: TCnAESExpandedKey256 - չ AES256 Կ + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const InitVector: TCnAESCTRIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// ============== ַʮַ֮ļӽ =================== + +function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Iv: TCnAESBuffer - 16 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ģʽַתʮơ + + + Value: AnsiString - ַܵ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const Iv: TCnAESCTRIv - 8 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ʮַ + + + const HexStr: AnsiString - ܵʮַ + Key: AnsiString - AES ԿַȸݼȷΪ 162432 ֽڣ̫ضϣ #0 + const Nonce: TCnAESCTRNonce - 4 ֽ Nonce + const Iv: TCnAESCTRIv - 8 ֽڳʼ + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ַ +} + +// ================= ֽֽ֮ļӽ ==================== + +function AESEncryptEcbBytes(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptEcbBytes(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCbcBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptOfbBytes(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESDecryptCtrBytes(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ģʽֽ顣 + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce 飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +// ============== ֽʮַ֮ļӽ ================= + +function AESEncryptEcbBytesToHex(Value: TBytes; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES ECB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES ECB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCbcBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CBC ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CBC ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CFB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CFB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptOfbBytesToHex(Value: TBytes; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES OFB ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES OFB ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Iv: TBytes - 16 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +function AESEncryptCtrBytesToHex(Value: TBytes; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): AnsiString; +{* AES CTR ģʽֽ鲢תʮơ + + + Value: TBytes - ֽܵ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵAnsiString - ʮַ +} + +function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key: TBytes; Nonce: TBytes; Iv: TBytes; + KeyBit: TCnKeyBitType = kbt128): TBytes; +{* AES CTR ʮַֽ顣 + + + const HexStr: AnsiString - ܵʮַ + Key: TBytes - AES Կֽ飬ȸݼȷΪ 162432 ֽڣ̫ضϣ 0 + Nonce: TBytes - 4 ֽ Nonce ֽ飬̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼֽ飬̫ضϣ 0 + KeyBit: TCnKeyBitType - AES + + ֵTBytes - ֽ +} + +implementation + +resourcestring + SCnErrorAESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; + SCnErrorAESReadError = 'Stream Read Error'; + SCnErrorAESWriteError = 'Stream Write Error'; + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +const + Rcon: array [1..30] of Cardinal = ( + $00000001, $00000002, $00000004, $00000008, $00000010, $00000020, + $00000040, $00000080, $0000001B, $00000036, $0000006C, $000000D8, + $000000AB, $0000004D, $0000009A, $0000002F, $0000005E, $000000BC, + $00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4, + $000000B3, $0000007D, $000000FA, $000000EF, $000000C5, $00000091 + ); + + ForwardTable: array [0..255] of Cardinal = ( + $A56363C6, $847C7CF8, $997777EE, $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591, + $50303060, $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC, + $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB, + $ECADAD41, $67D4D4B3, $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B, + $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E, $02F7F7F5, $4FCCCC83, + $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2, $73D8D8AB, $53313162, $3F15152A, + $0C040408, $52C7C795, $65232346, $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F, + $0907070E, $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA, + $1B090912, $9E83831D, $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B, + $F65252A4, $4D3B3B76, $61D6D6B7, $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413, + $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179, $ED5B5BB6, + $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98, $E85858B0, $4ACFCF85, + $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511, + $CF45458A, $10F9F9E9, $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B, + $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05, $AD92923F, $BC9D9D21, $48383870, $04F5F5F1, + $DFBCBC63, $C1B6B677, $75DADAAF, $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF, + $4CCDCD81, $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E, + $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932, $957373E6, + $A06060C0, $98818119, $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B, + $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7, $E25E5EBC, $1D0B0B16, $76DBDBAD, + $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992, $0A06060C, $6C242448, $E45C5CB8, + $5DC2C29F, $6ED3D3BD, $EFACAC43, $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2, + $32E7E7D5, $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949, + $B46C6CD8, $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810, + $D5BABA6F, $887878F0, $6F25254A, $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473, $51C6C697, + $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61, $868B8B0D, $858A8A0F, + $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890, $05030306, $01F6F6F7, $120E0E1C, + $A36161C2, $5F35356A, $F95757AE, $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27, + $38E1E1D9, $13F8F8EB, $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433, + $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9, $49CECE87, $FF5555AA, $78282850, $7ADFDFA5, + $8F8C8C03, $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0, + $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D, $3A16162C + ); + + LastForwardTable: array [0..255] of Cardinal = ( + $00000063, $0000007C, $00000077, $0000007B, $000000F2, $0000006B, $0000006F, $000000C5, + $00000030, $00000001, $00000067, $0000002B, $000000FE, $000000D7, $000000AB, $00000076, + $000000CA, $00000082, $000000C9, $0000007D, $000000FA, $00000059, $00000047, $000000F0, + $000000AD, $000000D4, $000000A2, $000000AF, $0000009C, $000000A4, $00000072, $000000C0, + $000000B7, $000000FD, $00000093, $00000026, $00000036, $0000003F, $000000F7, $000000CC, + $00000034, $000000A5, $000000E5, $000000F1, $00000071, $000000D8, $00000031, $00000015, + $00000004, $000000C7, $00000023, $000000C3, $00000018, $00000096, $00000005, $0000009A, + $00000007, $00000012, $00000080, $000000E2, $000000EB, $00000027, $000000B2, $00000075, + $00000009, $00000083, $0000002C, $0000001A, $0000001B, $0000006E, $0000005A, $000000A0, + $00000052, $0000003B, $000000D6, $000000B3, $00000029, $000000E3, $0000002F, $00000084, + $00000053, $000000D1, $00000000, $000000ED, $00000020, $000000FC, $000000B1, $0000005B, + $0000006A, $000000CB, $000000BE, $00000039, $0000004A, $0000004C, $00000058, $000000CF, + $000000D0, $000000EF, $000000AA, $000000FB, $00000043, $0000004D, $00000033, $00000085, + $00000045, $000000F9, $00000002, $0000007F, $00000050, $0000003C, $0000009F, $000000A8, + $00000051, $000000A3, $00000040, $0000008F, $00000092, $0000009D, $00000038, $000000F5, + $000000BC, $000000B6, $000000DA, $00000021, $00000010, $000000FF, $000000F3, $000000D2, + $000000CD, $0000000C, $00000013, $000000EC, $0000005F, $00000097, $00000044, $00000017, + $000000C4, $000000A7, $0000007E, $0000003D, $00000064, $0000005D, $00000019, $00000073, + $00000060, $00000081, $0000004F, $000000DC, $00000022, $0000002A, $00000090, $00000088, + $00000046, $000000EE, $000000B8, $00000014, $000000DE, $0000005E, $0000000B, $000000DB, + $000000E0, $00000032, $0000003A, $0000000A, $00000049, $00000006, $00000024, $0000005C, + $000000C2, $000000D3, $000000AC, $00000062, $00000091, $00000095, $000000E4, $00000079, + $000000E7, $000000C8, $00000037, $0000006D, $0000008D, $000000D5, $0000004E, $000000A9, + $0000006C, $00000056, $000000F4, $000000EA, $00000065, $0000007A, $000000AE, $00000008, + $000000BA, $00000078, $00000025, $0000002E, $0000001C, $000000A6, $000000B4, $000000C6, + $000000E8, $000000DD, $00000074, $0000001F, $0000004B, $000000BD, $0000008B, $0000008A, + $00000070, $0000003E, $000000B5, $00000066, $00000048, $00000003, $000000F6, $0000000E, + $00000061, $00000035, $00000057, $000000B9, $00000086, $000000C1, $0000001D, $0000009E, + $000000E1, $000000F8, $00000098, $00000011, $00000069, $000000D9, $0000008E, $00000094, + $0000009B, $0000001E, $00000087, $000000E9, $000000CE, $00000055, $00000028, $000000DF, + $0000008C, $000000A1, $00000089, $0000000D, $000000BF, $000000E6, $00000042, $00000068, + $00000041, $00000099, $0000002D, $0000000F, $000000B0, $00000054, $000000BB, $00000016 + ); + + InverseTable: array [0..255] of Cardinal = ( + $50A7F451, $5365417E, $C3A4171A, $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B, + $55FA3020, $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5, + $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B, + $E75F8F03, $959C9215, $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E, + $6A89C275, $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0, $66AC20C9, $B43ACE7D, + $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1, $84AE6BBB, $1CA081FE, $942B08F9, + $58684870, $19FD458F, $876CDE94, $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566, + $0728EBB2, $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED, + $2B1CCF8A, $92B479A7, $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4, + $9D532E34, $A055F3A2, $32E18A05, $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD, + $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604, $FF155060, + $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907, $385B19E7, $DBEEC879, + $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C, + $FBFF0EFD, $5638850F, $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624, + $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B, $4FC5C080, $A220DC61, $694B775A, $161A121C, + $0ABA93E2, $E52AA0C0, $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14, + $8519F157, $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B, + $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713, $2011C684, + $7D244A85, $F83DBBD2, $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177, + $6C16B32B, $99B970A9, $FA489411, $2264E947, $C48CFCA8, $1A3FF0A0, $D82C7D56, $EF903322, + $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6, $28DE7AA5, $268EB7DA, $A4BFAD3F, + $E49D3A2C, $0D927850, $9BCC5F6A, $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382, + $BE805D9F, $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB, + $097826CD, $F418596E, $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF, + $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029, $AFB2A431, $31233F2A, $3094A5C6, $C066A235, + $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41, $0E50CD7F, $2FF69117, + $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E, $1B886A4C, $B81F2CC1, $7F516546, + $04EA5E9D, $5D358C01, $737487FA, $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, + $8C61D79A, $7A0CA137, $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A, + $59DFD29C, $3F73F255, $79CE1418, $BF37C773, $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478, + $81F3AFCA, $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF, + $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48, $4257B8D0 + ); + + LastInverseTable: array [0..255] of Cardinal = ( + $00000052, $00000009, $0000006A, $000000D5, $00000030, $00000036, $000000A5, $00000038, + $000000BF, $00000040, $000000A3, $0000009E, $00000081, $000000F3, $000000D7, $000000FB, + $0000007C, $000000E3, $00000039, $00000082, $0000009B, $0000002F, $000000FF, $00000087, + $00000034, $0000008E, $00000043, $00000044, $000000C4, $000000DE, $000000E9, $000000CB, + $00000054, $0000007B, $00000094, $00000032, $000000A6, $000000C2, $00000023, $0000003D, + $000000EE, $0000004C, $00000095, $0000000B, $00000042, $000000FA, $000000C3, $0000004E, + $00000008, $0000002E, $000000A1, $00000066, $00000028, $000000D9, $00000024, $000000B2, + $00000076, $0000005B, $000000A2, $00000049, $0000006D, $0000008B, $000000D1, $00000025, + $00000072, $000000F8, $000000F6, $00000064, $00000086, $00000068, $00000098, $00000016, + $000000D4, $000000A4, $0000005C, $000000CC, $0000005D, $00000065, $000000B6, $00000092, + $0000006C, $00000070, $00000048, $00000050, $000000FD, $000000ED, $000000B9, $000000DA, + $0000005E, $00000015, $00000046, $00000057, $000000A7, $0000008D, $0000009D, $00000084, + $00000090, $000000D8, $000000AB, $00000000, $0000008C, $000000BC, $000000D3, $0000000A, + $000000F7, $000000E4, $00000058, $00000005, $000000B8, $000000B3, $00000045, $00000006, + $000000D0, $0000002C, $0000001E, $0000008F, $000000CA, $0000003F, $0000000F, $00000002, + $000000C1, $000000AF, $000000BD, $00000003, $00000001, $00000013, $0000008A, $0000006B, + $0000003A, $00000091, $00000011, $00000041, $0000004F, $00000067, $000000DC, $000000EA, + $00000097, $000000F2, $000000CF, $000000CE, $000000F0, $000000B4, $000000E6, $00000073, + $00000096, $000000AC, $00000074, $00000022, $000000E7, $000000AD, $00000035, $00000085, + $000000E2, $000000F9, $00000037, $000000E8, $0000001C, $00000075, $000000DF, $0000006E, + $00000047, $000000F1, $0000001A, $00000071, $0000001D, $00000029, $000000C5, $00000089, + $0000006F, $000000B7, $00000062, $0000000E, $000000AA, $00000018, $000000BE, $0000001B, + $000000FC, $00000056, $0000003E, $0000004B, $000000C6, $000000D2, $00000079, $00000020, + $0000009A, $000000DB, $000000C0, $000000FE, $00000078, $000000CD, $0000005A, $000000F4, + $0000001F, $000000DD, $000000A8, $00000033, $00000088, $00000007, $000000C7, $00000031, + $000000B1, $00000012, $00000010, $00000059, $00000027, $00000080, $000000EC, $0000005F, + $00000060, $00000051, $0000007F, $000000A9, $00000019, $000000B5, $0000004A, $0000000D, + $0000002D, $000000E5, $0000007A, $0000009F, $00000093, $000000C9, $0000009C, $000000EF, + $000000A0, $000000E0, $0000003B, $0000004D, $000000AE, $0000002A, $000000F5, $000000B0, + $000000C8, $000000EB, $000000BB, $0000003C, $00000083, $00000053, $00000099, $00000061, + $00000017, $0000002B, $00000004, $0000007E, $000000BA, $00000077, $000000D6, $00000026, + $000000E1, $00000069, $00000014, $00000063, $00000055, $00000021, $0000000C, $0000007D + ); + +procedure ExpandAESKeyForEncryption128(const Key: TCnAESKey128; var ExpandedKey: + TCnAESExpandedKey128); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 3] shl 24) or (ExpandedKey[I + 3] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 4] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 5] := ExpandedKey[I + 1] xor ExpandedKey[I + 4]; + ExpandedKey[I + 6] := ExpandedKey[I + 2] xor ExpandedKey[I + 5]; + ExpandedKey[I + 7] := ExpandedKey[I + 3] xor ExpandedKey[I + 6]; + Inc(I, 4); + until I >= 40; +end; + +procedure ExpandAESKeyForEncryption192(const Key: TCnAESKey192; var ExpandedKey: + TCnAESExpandedKey192); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + ExpandedKey[4] := PCardinal(@Key[16])^; + ExpandedKey[5] := PCardinal(@Key[20])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 5] shl 24) or (ExpandedKey[I + 5] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 6] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 7] := ExpandedKey[I + 1] xor ExpandedKey[I + 6]; + ExpandedKey[I + 8] := ExpandedKey[I + 2] xor ExpandedKey[I + 7]; + ExpandedKey[I + 9] := ExpandedKey[I + 3] xor ExpandedKey[I + 8]; + ExpandedKey[I + 10] := ExpandedKey[I + 4] xor ExpandedKey[I + 9]; + ExpandedKey[I + 11] := ExpandedKey[I + 5] xor ExpandedKey[I + 10]; + Inc(I, 6); + until I >= 46; +end; + +procedure ExpandAESKeyForEncryption256(const Key: TCnAESKey256; var ExpandedKey: + TCnAESExpandedKey256); +var + I, J: Integer; + T: Cardinal; + W0, W1, W2, W3: Cardinal; +begin + ExpandedKey[0] := PCardinal(@Key[0])^; + ExpandedKey[1] := PCardinal(@Key[4])^; + ExpandedKey[2] := PCardinal(@Key[8])^; + ExpandedKey[3] := PCardinal(@Key[12])^; + ExpandedKey[4] := PCardinal(@Key[16])^; + ExpandedKey[5] := PCardinal(@Key[20])^; + ExpandedKey[6] := PCardinal(@Key[24])^; + ExpandedKey[7] := PCardinal(@Key[28])^; + I := 0; J := 1; + repeat + T := (ExpandedKey[I + 7] shl 24) or (ExpandedKey[I + 7] shr 8); + W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)]; + W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)]; + ExpandedKey[I + 8] := ExpandedKey[I] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J]; + Inc(J); + ExpandedKey[I + 9] := ExpandedKey[I + 1] xor ExpandedKey[I + 8]; + ExpandedKey[I + 10] := ExpandedKey[I + 2] xor ExpandedKey[I + 9]; + ExpandedKey[I + 11] := ExpandedKey[I + 3] xor ExpandedKey[I + 10]; + W0 := LastForwardTable[Byte(ExpandedKey[I + 11])]; + W1 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 8)]; + W2 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 16)]; + W3 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 24)]; + ExpandedKey[I + 12] := ExpandedKey[I + 4] xor + (W0 xor ((W1 shl 8) or (W1 shr 24)) xor + ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))); + ExpandedKey[I + 13] := ExpandedKey[I + 5] xor ExpandedKey[I + 12]; + ExpandedKey[I + 14] := ExpandedKey[I + 6] xor ExpandedKey[I + 13]; + ExpandedKey[I + 15] := ExpandedKey[I + 7] xor ExpandedKey[I + 14]; + Inc(I, 8); + until I >= 52; +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +begin + EncryptAES128(InBuf, Key, OutBuf); +end; + +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +begin + EncryptAES192(InBuf, Key, OutBuf); +end; + +procedure EncryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +begin + EncryptAES256(InBuf, Key, OutBuf); +end; + +{$ENDIF} + +procedure EncryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 9 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure EncryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 11 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 10 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 11 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure EncryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[0]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[1]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[2]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[3]; + + // performing transformation 13 times + // round 1 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // round 2 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 3 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 4 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 5 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 9 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 10 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 11 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 12 + W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)]; + W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)]; + W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)]; + W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)]; + W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + // round 13 + W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)]; + W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; + W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)]; + W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; + W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)]; + W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; + W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)]; + W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; + // last round of transformations + W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)]; + W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[56]; + W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)]; + W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[57]; + W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)]; + W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[58]; + W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)]; + W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[59]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey128); +begin + ExpandAESKeyForDecryption128(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey128; + var ExpandedKey: TCnAESExpandedKey128); +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey192); +begin + ExpandAESKeyForDecryption192(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey192; + var ExpandedKey: TCnAESExpandedKey192); +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(var ExpandedKey: TCnAESExpandedKey256); +begin + ExpandAESKeyForDecryption256(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption(const Key: TCnAESKey256; + var ExpandedKey: TCnAESExpandedKey256); +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); +end; + +{$ENDIF} + +procedure ExpandAESKeyForDecryption128(var ExpandedKey: TCnAESExpandedKey128); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 9 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption128Expanded(const Key: TCnAESKey128; var ExpandedKey: + TCnAESExpandedKey128); +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + ExpandAESKeyForDecryption128(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption192(var ExpandedKey: TCnAESExpandedKey192); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 11 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption192Expanded(const Key: TCnAESKey192; var ExpandedKey: + TCnAESExpandedKey192); +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + ExpandAESKeyForDecryption192(ExpandedKey); +end; + +procedure ExpandAESKeyForDecryption256(var ExpandedKey: TCnAESExpandedKey256); +var + I: Integer; + U, F2, F4, F8, F9: Cardinal; +begin + for I := 1 to 13 do + begin + F9 := ExpandedKey[I * 4]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 1]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 2]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + F9 := ExpandedKey[I * 4 + 3]; + U := F9 and $80808080; + F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F2 and $80808080; + F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + U := F4 and $80808080; + F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B); + F9 := F9 xor F8; + ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor + (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor + (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24)); + end; +end; + +procedure ExpandAESKeyForDecryption256Expanded(const Key: TCnAESKey256; var ExpandedKey: + TCnAESExpandedKey256); +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + ExpandAESKeyForDecryption256(ExpandedKey); +end; + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +begin + DecryptAES128(InBuf, Key, OutBuf); +end; + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +begin + DecryptAES192(InBuf, Key, OutBuf); +end; + +procedure DecryptAES(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +begin + DecryptAES256(InBuf, Key, OutBuf); +end; + +{$ENDIF} + +procedure DecryptAES128(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey128; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[40]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[41]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[42]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[43]; + + // performing transformations 9 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure DecryptAES192(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey192; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[48]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[49]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[50]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[51]; + + // performing transformations 11 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 10 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 11 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +procedure DecryptAES256(const InBuf: TCnAESBuffer; const Key: TCnAESExpandedKey256; + var OutBuf: TCnAESBuffer); +var + T0, T1: array [0..3] of Cardinal; + W0, W1, W2, W3: Cardinal; +begin + // initializing + T0[0] := PCardinal(@InBuf[0])^ xor Key[56]; + T0[1] := PCardinal(@InBuf[4])^ xor Key[57]; + T0[2] := PCardinal(@InBuf[8])^ xor Key[58]; + T0[3] := PCardinal(@InBuf[12])^ xor Key[59]; + + // performing transformations 13 times + // round 1 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[52]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[53]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[54]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[55]; + // round 2 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[48]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[49]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[50]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[51]; + // round 3 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[44]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[45]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[46]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[47]; + // round 4 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[40]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[41]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[42]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[43]; + // round 5 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[36]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[37]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[38]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[39]; + // round 6 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[32]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[33]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[34]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[35]; + // round 7 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[28]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[29]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[30]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[31]; + // round 8 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[24]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[25]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[26]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[27]; + // round 9 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[20]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[21]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[22]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[23]; + // round 10 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[16]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[17]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[18]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[19]; + // round 11 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[12]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[13]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[14]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[15]; + // round 12 + W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)]; + W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[8]; + W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)]; + W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[9]; + W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)]; + W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[10]; + W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)]; + W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[11]; + // round 13 + W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)]; + W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)]; + T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[4]; + W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)]; + W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)]; + T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[5]; + W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)]; + W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)]; + T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[6]; + W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)]; + W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)]; + T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[7]; + // last round of transformations + W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)]; + W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)]; + T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[0]; + W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)]; + W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)]; + T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[1]; + W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)]; + W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)]; + T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[2]; + W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)]; + W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)]; + T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) + xor ((W3 shl 24) or (W3 shr 8))) xor Key[3]; + + // finalizing + PCardinal(@OutBuf[0])^ := T0[0]; + PCardinal(@OutBuf[4])^ := T0[1]; + PCardinal(@OutBuf[8])^ := T0[2]; + PCardinal(@OutBuf[12])^ := T0[3]; +end; + +// Stream Encryption Routines (ECB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +begin + EncryptAES128StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +begin + EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +begin + EncryptAES192StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +begin + EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +begin + EncryptAES256StreamECB(Source, Count, Key, Dest); +end; + +procedure EncryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +begin + EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure EncryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (ECB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +begin + DecryptAES128StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +begin + DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +begin + DecryptAES192StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +begin + DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +begin + DecryptAES256StreamECB(Source, Count, Key, Dest); +end; + +procedure DecryptAESStreamECB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +begin + DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); + DecryptAES128StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES128StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES192StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); + DecryptAES192StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES192StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES256StreamECB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); + DecryptAES256StreamECBExpanded(Source, Count, ExpandedKey, Dest); +end; + +procedure DecryptAES256StreamECBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + DecryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +// Stream Encryption Routines (CBC mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); // Ҫÿһ鶼 + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; // ԭʼ IV + EncryptAES128(TempIn, ExpandedKey, TempOut); // ټ + Done := Dest.Write(TempOut, SizeOf(TempOut)); // д + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // ݴԭʼ IV һʹ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES128(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES192(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@Vector[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@Vector[12])^; + EncryptAES256(TempIn, ExpandedKey, TempOut); + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CBC mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamCBC(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCBC(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForDecryption128Expanded(Key, ExpandedKey); + DecryptAES128StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES128(TempIn, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES192StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForDecryption192Expanded(Key, ExpandedKey); + DecryptAES192StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES192(TempIn, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +procedure DecryptAES256StreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForDecryption256Expanded(Key, ExpandedKey); + DecryptAES256StreamCBCExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamCBCExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector1, Vector2: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + if (Count mod SizeOf(TCnAESBuffer)) > 0 then + raise ECnAESException.Create(SCnErrorAESInvalidInBufSize); // CBC Ϊ AES ֿܲģԱ + Vector1 := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + Vector2 := TempIn; + DecryptAES256(TempIn, ExpandedKey, TempOut); // Ƚ + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; // ܺݺ Iv õ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@Vector1[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@Vector1[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector1 := Vector2; // ȡ Iv Ϊһκͽ + Dec(Count, SizeOf(TCnAESBuffer)); + end; +end; + +// Stream Encryption Routines (CFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // ĽдĽ + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // Ľȡ Iv һּ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamCFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamCFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + // CFB Ϊ AES ֿܲĶ򣨳Ŀɶ + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); // + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); // дȥ + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; // ȡ Iv Ϊһμ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then // һ鲻Ϊ + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); // дȥ + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES192StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES256StreamCFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamCFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamCFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempIn; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempOut[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempOut[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempOut, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +// Stream Encryption Routines (OFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + EncryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure EncryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; // ܽȡ Iv һּܣעⲻ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure EncryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (OFB mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES128StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES192StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +begin + DecryptAES256StreamOFB(Source, Count, Key, InitVector, Dest); +end; + +procedure DecryptAESStreamOFB(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +begin + DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES128StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + // OFB Ϊ AES ֿܲĶ򣨳Ŀɶ + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); // + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); // Iv ȼܡעǼܣǽܣ + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // дȥ + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; // ȡ Iv Ϊһǰ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then // һ鲻Ϊ + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; // ܺݺõ + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); // дȥ + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES192StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES192StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +procedure DecryptAES256StreamOFB(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const InitVector: TCnAESBuffer; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamOFBExpanded(Source, Count, ExpandedKey, InitVector, Dest); +end; + +procedure DecryptAES256StreamOFBExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const InitVector: TCnAESBuffer; + Dest: TStream); +var + TempIn, TempOut: TCnAESBuffer; + Vector: TCnAESBuffer; + Done: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Vector := InitVector; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorAESWriteError); + Vector := TempOut; + Dec(Count, SizeOf(TCnAESBuffer)); + end; + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESReadError); + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@TempIn[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@TempIn[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempOut[8])^ xor PCardinal(@TempIn[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempOut[12])^ xor PCardinal(@TempIn[12])^; + Done := Dest.Write(TempIn, Count); + if Done < Count then + raise EStreamError(SCnErrorAESWriteError); + end; +end; + +// Stream Encryption Routines (CTR mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure EncryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +{$ENDIF} + +procedure EncryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES128(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES128(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES192(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES192(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +procedure EncryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure EncryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + TempIn, TempOut, Vector: TCnAESBuffer; + Done, Cnt, T: Cardinal; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else Count := Min(Count, Source.Size - Source.Position); + if Count = 0 then Exit; + + Cnt := 1; + while Count >= SizeOf(TCnAESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES256(Vector, ExpandedKey, TempOut); // Key ȼƴ Iv + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; // ܽ + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, SizeOf(TempIn)); // ĽдĽ + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorAESWriteError); + + Inc(Cnt); // һ + Dec(Count, SizeOf(TCnAESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorAESReadError); + + Move(Nonce[0], Vector[0], SizeOf(TCnAESCTRNonce)); + Move(InitVector[0], Vector[SizeOf(TCnAESCTRNonce)], SizeOf(TCnAESCTRIv)); + T := UInt32HostToNetwork(Cnt); + Move(T, Vector[SizeOf(TCnAESCTRNonce) + SizeOf(TCnAESCTRIv)], SizeOf(Cardinal)); + + EncryptAES256(Vector, ExpandedKey, TempOut); + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@TempOut[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@TempOut[4])^; + PCardinal(@TempIn[8])^ := PCardinal(@TempIn[8])^ xor PCardinal(@TempOut[8])^; + PCardinal(@TempIn[12])^ := PCardinal(@TempIn[12])^ xor PCardinal(@TempOut[12])^; + Done := Dest.Write(TempIn, Count); // дֻijȵIJ֣ + if Done < Count then + raise EStreamError.Create(SCnErrorAESWriteError); + end; +end; + +// Stream Decryption Routines (CTR mode) + +{$IFNDEF BCB5OR6} + +// C++Builder overload ⣬ Delphi ¿ +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES128StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES192StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES256StreamCTR(Source, Count, Key, Nonce, InitVector, Dest); +end; + +procedure DecryptAESStreamCTR(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +{$ENDIF} + +procedure DecryptAES128StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey128; +begin + ExpandAESKeyForEncryption128(Key, ExpandedKey); + DecryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES128StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey128; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES128StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES192StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey192; +begin + ExpandAESKeyForEncryption192(Key, ExpandedKey); + DecryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES192StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey192; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES192StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES256StreamCTR(Source: TStream; Count: Cardinal; + const Key: TCnAESKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +var + ExpandedKey: TCnAESExpandedKey256; +begin + ExpandAESKeyForEncryption256(Key, ExpandedKey); + DecryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +procedure DecryptAES256StreamCTRExpanded(Source: TStream; Count: Cardinal; + const ExpandedKey: TCnAESExpandedKey256; const Nonce: TCnAESCTRNonce; + const InitVector: TCnAESCTRIv; Dest: TStream); +begin + EncryptAES256StreamCTRExpanded(Source, Count, ExpandedKey, Nonce, InitVector, Dest); +end; + +// AES ECB ַתʮ +function AESEncryptEcbStrToHex(Value: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamECB(SS, 0, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamECB(SS, 0, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamECB(SS, 0, AESKey256, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ʮַ +function AESDecryptEcbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ַתʮ +function AESEncryptCbcStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCBC(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCBC(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCBC(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ʮַ +function AESDecryptCbcStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽַתʮ +function AESEncryptCfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCFB(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCFB(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCFB(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ʮַ +function AESDecryptCfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽַתʮ +function AESEncryptOfbStrToHex(Value: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamOFB(SS, 0, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamOFB(SS, 0, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamOFB(SS, 0, AESKey256, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ʮַ +function AESDecryptOfbStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Iv: TCnAESBuffer; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽַתʮ +function AESEncryptCtrStrToHex(Value: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[1])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCTR(SS, 0, AESKey128, Nonce, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCTR(SS, 0, AESKey192, Nonce, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCTR(SS, 0, AESKey256, Nonce, Iv, DS); + end; + end; + + Result := AnsiString(DataToHex(DS.Memory, DS.Size)); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ʮַ +function AESDecryptCtrStrFromHex(const HexStr: AnsiString; Key: AnsiString; + const Nonce: TCnAESCTRNonce; const Iv: TCnAESCTRIv; KeyBit: TCnKeyBitType): AnsiString; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + Tmp: TBytes; +begin + Result := ''; + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + Tmp := HexToBytes(string(HexStr)); + SS.Write(PAnsiChar(@Tmp[0])^, Length(Tmp)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, Nonce, Iv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, Nonce, Iv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, Nonce, Iv, DS); + end; + end; + + SetLength(Result, DS.Size); + Move(PAnsiChar(DS.Memory)^, Result[1], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ +function AESEncryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamECB(SS, 0, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamECB(SS, 0, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamECB(SS, 0, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ +function AESDecryptEcbBytes(Value, Key: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamECB(SS, SS.Size - SS.Position, AESKey128, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamECB(SS, SS.Size - SS.Position, AESKey192, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamECB(SS, SS.Size - SS.Position, AESKey256, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ģʽֽ +function AESEncryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCBC(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCBC(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCBC(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CBC ģʽֽ +function AESDecryptCbcBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCBC(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCBC(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCBC(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽֽ +function AESEncryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCFB(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCFB(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCFB(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CFB ģʽֽ +function AESDecryptCfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽֽ +function AESEncryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamOFB(SS, 0, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamOFB(SS, 0, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamOFB(SS, 0, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES OFB ģʽֽ +function AESDecryptOfbBytes(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESBuffer; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamOFB(SS, SS.Size - SS.Position, AESKey128, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamOFB(SS, SS.Size - SS.Position, AESKey192, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamOFB(SS, SS.Size - SS.Position, AESKey256, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽֽ +function AESEncryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESCTRIv; + AESNonce: TCnAESCTRNonce; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + + FillChar(AESNonce, SizeOF(AESNonce), 0); + Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + EncryptAES128StreamCTR(SS, 0, AESKey128, AESNonce, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + EncryptAES192StreamCTR(SS, 0, AESKey192, AESNonce, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + EncryptAES256StreamCTR(SS, 0, AESKey256, AESNonce, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES CTR ģʽֽ +function AESDecryptCtrBytes(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): TBytes; +var + SS, DS: TMemoryStream; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AESIv: TCnAESCTRIv; + AESNonce: TCnAESCTRNonce; +begin + if Length(Value) <= 0 then + begin + Result := nil; + Exit; + end; + + SS := nil; + DS := nil; + + try + SS := TMemoryStream.Create; + SS.Write(PAnsiChar(@Value[0])^, Length(Value)); + SS.Position := 0; + + FillChar(AESIv, SizeOF(AESIv), 0); + Move(PAnsiChar(Iv)^, AESIv, Min(SizeOf(AESIv), Length(Iv))); + + FillChar(AESNonce, SizeOF(AESNonce), 0); + Move(PAnsiChar(Nonce)^, AESNonce, Min(SizeOf(AESNonce), Length(Nonce))); + DS := TMemoryStream.Create; + + case KeyBit of + kbt128: + begin + FillChar(AESKey128, SizeOf(AESKey128), 0); + Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key))); + DecryptAES128StreamCTR(SS, SS.Size - SS.Position, AESKey128, AESNonce, AESIv, DS); + end; + kbt192: + begin + FillChar(AESKey192, SizeOf(AESKey192), 0); + Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key))); + DecryptAES192StreamCTR(SS, SS.Size - SS.Position, AESKey192, AESNonce, AESIv, DS); + end; + kbt256: + begin + FillChar(AESKey256, SizeOf(AESKey256), 0); + Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key))); + DecryptAES256StreamCTR(SS, SS.Size - SS.Position, AESKey256, AESNonce, AESIv, DS); + end; + end; + + SetLength(Result, DS.Size); + DS.Position := 0; + DS.Read(Result[0], DS.Size); + finally + SS.Free; + DS.Free; + end; +end; + +// AES ECB ģʽֽ鲢תʮ +function AESEncryptEcbBytesToHex(Value, Key: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptEcbBytes(Value, Key, KeyBit))); +end; + +// AES ECB ʮַֽ +function AESDecryptEcbBytesFromHex(const HexStr: AnsiString; Key: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptEcbBytes(HexToBytes(string(HexStr)), Key, KeyBit); +end; + +// AES CBC ģʽֽ鲢תʮ +function AESEncryptCbcBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCbcBytes(Value, Key, Iv, KeyBit))); +end; + +// AES CBC ʮַֽ +function AESDecryptCbcBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCbcBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES CFB ģʽֽ鲢תʮ +function AESEncryptCfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCfbBytes(Value, Key, Iv, KeyBit))); +end; + +// AES CFB ʮַֽ +function AESDecryptCfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES OFB ģʽֽ鲢תʮ +function AESEncryptOfbBytesToHex(Value, Key, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptOfbBytes(Value, Key, Iv, KeyBit))); +end; + +// AES OFB ʮַֽ +function AESDecryptOfbBytesFromHex(const HexStr: AnsiString; Key, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptOfbBytes(HexToBytes(string(HexStr)), Key, Iv, KeyBit); +end; + +// AES CTR ģʽֽ鲢תʮ +function AESEncryptCtrBytesToHex(Value, Key, Nonce, Iv: TBytes; KeyBit: TCnKeyBitType): AnsiString; +begin + Result := AnsiString(BytesToHex(AESEncryptCtrBytes(Value, Key, Nonce, Iv, KeyBit))); +end; + +// AES CTR ʮַֽ +function AESDecryptCtrBytesFromHex(const HexStr: AnsiString; Key, Nonce, Iv: TBytes; + KeyBit: TCnKeyBitType): TBytes; +begin + Result := AESDecryptCtrBytes(HexToBytes(string(HexStr)), Key, Nonce, Iv, KeyBit); +end; + +end. + diff --git a/CnPack/Crypto/CnBase64.dcu b/CnPack/Crypto/CnBase64.dcu new file mode 100644 index 0000000000000000000000000000000000000000..3b1d931f16324cb1df37a96014462e88b915a17e GIT binary patch literal 7426 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 U5XKli4!pF literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnBase64.pas b/CnPack/Crypto/CnBase64.pas new file mode 100644 index 0000000..cfe7dc1 --- /dev/null +++ b/CnPack/Crypto/CnBase64.pas @@ -0,0 +1,547 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{ -----------------------------------------------------------------------------} +{ uTBase64 v1.0 - Simple Base64 encoding/decoding class } +{ Base64 described in RFC2045, Page 24, (w) 1996 Freed & Borenstein } +{ Delphi implementation (w) 1999 Dennis D. Spreen (dennis@spreendigital.de) } +{ This unit is freeware. Just drop me a line if this unit is useful for you. } +{ -----------------------------------------------------------------------------} + +unit CnBase64; +{* |
+================================================================================
+* ƣ
+* ԪƣBase64 㷨ʵֵԪ
+* ԪߣղSolin solin@21cn.com; http://www.ilovezhuzhu.net
+*           wr960204
+*           CnPack  (master@cnpack.org)
+*           ݻ Dennis D. Spreen  UTBASE64.pas дԭаȨϢ
+*     עԪʵ˱׼ Base64  Base64URL ı빦ܡ
+*           Base64URL ڱ׼ Base64ѷ + / 滻 - _  URL 
+*           Ѻãɾβ =
+*
+* ƽ̨PWin2003Std + Delphi 6.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2023.10.04 V1.6
+*               ɾʵ֡Base64Encode  Base64Decode ֧ Base64URL ı
+*           2019.12.12 V1.5
+*               ֧ TBytes
+*           2019.04.15 V1.4
+*               ֧ Win32/Win64/MacOS
+*           2018.06.22 V1.3
+*               ԭʼݿܰ #0 ԭʼβ #0 Ƴ
+*           2016.05.03 V1.2
+*               ַа #0 ʱܻᱻضϵ
+*           2006.10.25 V1.1
+*                wr960204 Ż汾
+*           2003.10.14 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnConsts; + +const + ECN_BASE64_OK = ECN_OK; // תɹ + {* Base64 ϵд룺޴ֵΪ 0} + ECN_BASE64_ERROR_BASE = ECN_CUSTOM_ERROR_BASE + $500; + {* Base64 ϵдĻ׼ʼֵΪ ECN_CUSTOM_ERROR_BASE $500} + + ECN_BASE64_LENGTH = ECN_BASE64_ERROR_BASE + 1; + {* Base64 ֮ݳȷǷ} + +function Base64Encode(InputData: TStream; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: TStream - + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(const InputData: AnsiString; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ַ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + const InputData: AnsiString - ַ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ݿ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: Pointer - ݿַ + DataByteLen: Integer - ݿֽڳ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Encode(InputData: TBytes; var OutputData: string; + URL: Boolean = False): Integer; overload; +{* ֽ Base64 Base64URL 룬ɹ ECN_BASE64_OK + + + InputData: TBytes - ֽ + var OutputData: string - ַ + URL: Boolean - URL ǡTrue ʹ Base64URL 룬False ʹñ׼ Base64 + + ֵInteger - رǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; OutputData: TStream; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дɹ ECN_BASE64_OK + + + const InputData: string - ַ + OutputData: TStream - + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; var OutputData: AnsiString; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дַɹ ECN_BASE64_OK + + + const InputData: string - ַ + var OutputData: AnsiString - ַ + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; OutputData: Pointer; + DataByteLen: Integer; FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дڴɹ ECN_BASE64_OK + + + const InputData: string - ַ + OutputData: Pointer - ڴַ + DataByteLen: Integer - ڴֽڳȣӦΪ 1 + (Length(InputData) * 3 / 4) + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - OutputData nilĽֽڳȡؽǷɹɹ򷵻 ECN_BASE64_OK +} + +function Base64Decode(const InputData: string; out OutputData: TBytes; + FixZero: Boolean = True): Integer; overload; +{* ַ Base64 루 Base64URL 룩дֽ顣ɹ ECN_BASE64_OK + + + const InputData: string - ַ + out OutputData: TBytes - ֽ + FixZero: Boolean - Ƿȥβ #0 + + ֵInteger - ؽǷɹɹ򷵻 ECN_BASE64_OK +} + +implementation + +var + FilterDecodeInput: Boolean = True; + +//------------------------------------------------------------------------------ +// IJο +//------------------------------------------------------------------------------ + + EnCodeTab: array[0..64] of AnsiChar = + ( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/', + '='); + + EnCodeTabURL: array[0..64] of AnsiChar = + ( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '_', + '='); + +//------------------------------------------------------------------------------ +// IJο +//------------------------------------------------------------------------------ + + { Base64 ֱַӸ㣬Ҳȡ} + DecodeTable: array[#0..#127] of Byte = + ( + Byte('='), 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 62, 00, 62, 00, 63, // ĵһ 62 63 + / - 62 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00, 00, 00, 00, 00, 00, + 00, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 00, 00, 00, 00, 63, // _ 63 + 00, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 00, 00, 00, 00, 00 + ); + +function Base64Encode(InputData: TStream; var OutputData: string; URL: Boolean): Integer; +var + Mem: TMemoryStream; +begin + Mem := TMemoryStream.Create; + try + Mem.CopyFrom(InputData, InputData.Size); + Result := Base64Encode(Mem.Memory, Mem.Size, OutputData, URL); + finally + Mem.Free; + end; +end; + +// Ϊ wr960204 ĽĿ Base64 㷨 +function Base64Encode(InputData: Pointer; DataByteLen: Integer; var OutputData: string; + URL: Boolean): Integer; +var + Times, I: Integer; + X1, X2, X3, X4: AnsiChar; + XT: Byte; +begin + if (InputData = nil) or (DataByteLen <= 0) then + begin + Result := ECN_BASE64_LENGTH; + Exit; + end; + + if DataByteLen mod 3 = 0 then + Times := DataByteLen div 3 + else + Times := DataByteLen div 3 + 1; + SetLength(OutputData, Times * 4); // һηڴ,һδַ,һδͷŷڴ + FillChar(OutputData[1], Length(OutputData) * SizeOf(Char), 0); + + if URL then + begin + for I := 0 to Times - 1 do + begin + if DataByteLen >= (3 + I * 3) then + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); + X3 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); + X4 := EnCodeTabURL[XT]; + end + else if DataByteLen >= (2 + I * 3) then + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTabURL[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + X3 := EnCodeTabURL[XT ]; + X4 := '='; + end + else + begin + X1 := EnCodeTabURL[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + X2 := EnCodeTabURL[XT]; + X3 := '='; + X4 := '='; + end; + OutputData[I shl 2 + 1] := Char(X1); + OutputData[I shl 2 + 2] := Char(X2); + OutputData[I shl 2 + 3] := Char(X3); + OutputData[I shl 2 + 4] := Char(X4); + end; + end + else + begin + for I := 0 to Times - 1 do + begin + if DataByteLen >= (3 + I * 3) then + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + XT := XT or (Ord(PAnsiChar(InputData)[2 + I * 3]) shr 6); + X3 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[2 + I * 3]) and 63); + X4 := EnCodeTab[XT]; + end + else if DataByteLen >= (2 + I * 3) then + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + XT := XT or (Ord(PAnsiChar(InputData)[1 + I * 3]) shr 4); + X2 := EnCodeTab[XT]; + XT := (Ord(PAnsiChar(InputData)[1 + I * 3]) shl 2) and 60; + X3 := EnCodeTab[XT ]; + X4 := '='; + end + else + begin + X1 := EnCodeTab[(Ord(PAnsiChar(InputData)[I * 3]) shr 2)]; + XT := (Ord(PAnsiChar(InputData)[I * 3]) shl 4) and 48; + X2 := EnCodeTab[XT]; + X3 := '='; + X4 := '='; + end; + OutputData[I shl 2 + 1] := Char(X1); + OutputData[I shl 2 + 2] := Char(X2); + OutputData[I shl 2 + 3] := Char(X3); + OutputData[I shl 2 + 4] := Char(X4); + end; + end; + + OutputData := Trim(OutputData); + if URL then + begin + // ɾ OutputData β = ַ + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + begin + Delete(OutputData, Length(OutputData), 1); + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + begin + Delete(OutputData, Length(OutputData), 1); + if (Length(OutputData) > 0) and (OutputData[Length(OutputData)] = '=') then + Delete(OutputData, Length(OutputData), 1); + end; + end; + end; + Result := ECN_BASE64_OK; +end; + +function Base64Encode(const InputData: AnsiString; var OutputData: string; URL: Boolean): Integer; +begin + if InputData <> '' then + Result := Base64Encode(@InputData[1], Length(InputData), OutputData, URL) + else + Result := ECN_BASE64_LENGTH; +end; + +function Base64Encode(InputData: TBytes; var OutputData: string; URL: Boolean): Integer; +begin + if Length(InputData) > 0 then + Result := Base64Encode(@InputData[0], Length(InputData), OutputData, URL) + else + Result := ECN_BASE64_LENGTH; +end; + +function Base64Decode(const InputData: string; OutputData: TStream; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + OutputData.Size := Length(Data); + OutputData.Position := 0; + OutputData.Write(Data[0], Length(Data)); + end; +end; + +function Base64Decode(const InputData: string; out OutputData: TBytes; + FixZero: Boolean): Integer; +var + SrcLen, DstLen, Times, I: Integer; + X1, X2, X3, X4, XT: Byte; + C, ToDec: Integer; + Data: AnsiString; + + function FilterLine(const Source: AnsiString): AnsiString; + var + P, PP: PAnsiChar; + I, FL: Integer; + begin + FL := Length(Source); + if FL > 0 then + begin + GetMem(P, FL); // һηڴ,һδַ,һδͷŷڴ + PP := P; + FillChar(P^, FL, 0); + for I := 1 to FL do + begin + if Source[I] in ['0'..'9', 'A'..'Z', 'a'..'z', '+', '/', '=', '-', '_'] then + begin + PP^ := Source[I]; + Inc(PP); + end; + end; + SetString(Result, P, PP - P); // ȡЧ + FreeMem(P); + end; + end; + +begin + if InputData = '' then + begin + Result := ECN_BASE64_OK; + Exit; + end; + OutPutData := nil; + + // D5 ²֪ôIJ AnsiString(InputData)ܻڴֿ + if FilterDecodeInput then + begin +{$IFDEF UNICODE} + Data := FilterLine(AnsiString(InputData)); +{$ELSE} + Data := FilterLine(InputData); +{$ENDIF} + end + else + begin +{$IFDEF UNICODE} + Data := AnsiString(InputData); +{$ELSE} + Data := InputData; +{$ENDIF} + end; + + // Base64URL Ľȥβ =ҪݳǷ 4 ı + if (Length(Data) and $03) <> 0 then + Data := Data + StringOfChar(AnsiChar('='), 4 - (Length(Data) and $03)); + + SrcLen := Length(Data); + DstLen := SrcLen * 3 div 4; + ToDec := 0; + + // βһȺζԭʼݲ˸ #0ȺζŲ #0ҪȥҲ̳ + // עⲻͬԭʼݵβ #0 ȥ + if Data[SrcLen] = '=' then + begin + Inc(ToDec); + if (SrcLen > 1) and (Data[SrcLen - 1] = '=') then + Inc(ToDec); + end; + + SetLength(OutputData, DstLen); // һηڴ,һδַ,һδͷŷڴ + Times := SrcLen div 4; + C := 0; + + for I := 0 to Times - 1 do + begin + X1 := DecodeTable[Data[1 + I shl 2]]; + X2 := DecodeTable[Data[2 + I shl 2]]; + X3 := DecodeTable[Data[3 + I shl 2]]; + X4 := DecodeTable[Data[4 + I shl 2]]; + X1 := X1 shl 2; + XT := X2 shr 4; + X1 := X1 or XT; + X2 := X2 shl 4; + OutputData[C] := X1; + Inc(C); + if X3 = 64 then + Break; + XT := X3 shr 2; + X2 := X2 or XT; + X3 := X3 shl 6; + OutputData[C] := X2; + Inc(C); + if X4 = 64 then + Break; + X3 := X3 or X4; + OutputData[C] := X3; + Inc(C); + end; + + // ݲĵȺĿǷɾβ #0 + while (ToDec > 0) and (OutputData[DstLen - 1] = 0) do + begin + Dec(ToDec); + Dec(DstLen); + end; + SetLength(OutputData, DstLen); + + // ٸⲿҪɾβ #0ʵ̫ʵ + if FixZero then + begin + while (DstLen > 0) and (OutputData[DstLen - 1] = 0) do + Dec(DstLen); + SetLength(OutputData, DstLen); + end; + + Result := ECN_BASE64_OK; +end; + +function Base64Decode(const InputData: string; var OutputData: AnsiString; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + SetLength(OutputData, Length(Data)); + Move(Data[0], OutputData[1], Length(Data)); + end; +end; + +function Base64Decode(const InputData: string; OutputData: Pointer; + DataByteLen: Integer; FixZero: Boolean): Integer; +var + Data: TBytes; +begin + Result := Base64Decode(InputData, Data, FixZero); + if (Result = ECN_BASE64_OK) and (Length(Data) > 0) then + begin + if OutputData = nil then + begin + Result := Length(Data); + Exit; + end; + + if DataByteLen < Length(Data) then + begin + Result := ECN_BASE64_LENGTH; + Exit; + end; + + Move(Data[0], OutPutData^, Length(Data)); + end; +end; + +end. diff --git a/CnPack/Crypto/CnConsts.dcu b/CnPack/Crypto/CnConsts.dcu new file mode 100644 index 0000000000000000000000000000000000000000..c867ed279f4c00fe26ff633e118584d938e5bedb GIT binary patch literal 14305 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 e3USNw2)Y>N%(KXha^|S(k2<+r=u|5s literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnConsts.pas b/CnPack/Crypto/CnConsts.pas new file mode 100644 index 0000000..f4f50aa --- /dev/null +++ b/CnPack/Crypto/CnConsts.pas @@ -0,0 +1,250 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnConsts; +{* |
+================================================================================
+* ƣ
+* ԪƣԴַ嵥Ԫ
+* ԪߣCnPack 
+*     ע
+* ƽ̨PWin98SE + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2005.12.24 V1.0
+*                ԪֲӢַ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +const + ECN_OK = 0; // OK޴ + + ECN_FILE_NOT_FOUND = $10; // ļ + + ECN_CUSTOM_ERROR_BASE = $1000; // 趨Ĵʼֵ + +//============================================================================== +// Strings DO NOT Localize: +//============================================================================== + +resourcestring + + // CnPack Reg Path + SCnPackRegPath = '\Software\CnPack'; + + // Tools Reg Path + SCnPackToolRegPath = 'CnTools'; + +//============================================================================== +// Strings to be Localized: +//============================================================================== + + +var + // Common Information + SCnInformation: string = 'Information'; + SCnWarning: string = 'Warning'; + SCnError: string = 'Error'; + SCnEnabled: string = 'Enabled'; + SCnDisabled: string = 'Disabled'; + SCnMsgDlgOK: string = '&OK'; + SCnMsgDlgCancel: string = '&Cancel'; + SCnMsgDlgYes: string = '&Yes'; + SCnMsgDlgNo: string = '&No'; + SCnMsgDlgYesToAll: string = 'Yes to &All'; + SCnMsgDlgNoToAll: string = 'No to A&ll'; + SCnVersion: string = 'Version'; + SCnNeedAdmin: string = 'Maybe Need Administrator.'; + +const + // CnPack Information + SCnPackAbout = 'CnPack'; + SCnPackVer = 'Ver 0.1.5.2'; + SCnPackStr = SCnPackAbout + ' ' + SCnPackVer; + SCnPackUrl = 'https://www.cnpack.org'; + SCnPackBbsUrl = 'https://bbs.cnpack.org'; + SCnPackNewsUrl = 'news://news.cnpack.org'; + SCnPackSourceUrl = 'https://github.com/cnpack'; + SCnPackEmail = 'master@cnpack.org'; + SCnPackBugEmail = 'bugs@cnpack.org'; + SCnPackSuggestionsEmail = 'suggestions@cnpack.org'; + + SCnPackDonationUrl = 'https://www.cnpack.org/foundation.php'; + SCnPackDonationUrlSF = 'http://sourceforge.net/donate/index.php?group_id=110999'; + SCnPackGroup = 'CnPack Team'; + SCnPackCopyright = '(C)Copyright 2001-2025 ' + SCnPackGroup; + + // CnPropEditors + SCopyrightFmtStr = + SCnPackStr + #13#10#13#10 + + 'Component Name: %s' + #13#10 + + 'Author: %s(%s)' + #13#10 + + 'Comment: %s' + #13#10 + + 'HomePage: ' + SCnPackUrl + #13#10 + + 'Email: ' + SCnPackEmail + #13#10#13#10 + + SCnPackCopyright; + +resourcestring + + // Component Palette Name + SCnNonVisualPalette = 'CnPack Tools'; + SCnGraphicPalette = 'CnPack VCL'; + SCnNetPalette = 'CnPack Net'; + SCnDatabasePalette = 'CnPack DB'; + SCnReportPalette = 'CnPack Report'; + + // CnPack Developers Added from Last. +var + SCnPack_Team: string = 'CnPack Team'; + SCnPack_Zjy: string = 'Zhou JingYu'; + SCnPack_Shenloqi: string = 'Chinbo'; + SCnPack_xiaolv: string = 'xiaolv'; + SCnPack_Flier: string = 'Flier Lu'; + SCnPack_LiuXiao: string = 'Liu Xiao'; + SCnPack_PanYing: string = 'Pan Ying'; + SCnPack_Hubdog: string = 'Hubdog'; + SCnPack_Wyb_star: string = 'wyb_star'; + SCnPack_Licwing: string = 'Licwing zue'; + SCnPack_Alan: string = 'Alan'; + SCnPack_GuYueChunQiu: string = 'GuYueChunQiu'; + SCnPack_Aimingoo: string = 'Aimingoo'; + SCnPack_QSoft: string = 'QSoft'; + SCnPack_Hospitality: string = 'ZhangJiongXuan (Hospitality)'; + SCnPack_SQuall: string = 'SQUALL'; + SCnPack_Hhha: string = 'Hhha'; + SCnPack_Beta: string = 'beta'; + SCnPack_Leeon: string = 'Leeon'; + SCnPack_SuperYoyoNc: string = 'SuperYoyoNC'; + SCnPack_JohnsonZhong: string = 'Johnson Zhong'; + SCnPack_DragonPC: string = 'Dragon P.C.'; + SCnPack_Kendling: string = 'Kending'; + SCnPack_ccrun: string = 'ccrun'; + SCnPack_Dingbaosheng: string = 'dingbaosheng'; + SCnPack_LuXiaoban: string = 'Zhou Yibo(Lu Xiaoban)'; + SCnPack_Savetime: string = 'savetime'; + SCnPack_solokey: string = 'solokey'; + SCnPack_Bahamut: string = 'Bahamut'; + SCnPack_Sesame: string = 'Sesame'; + SCnPack_BuDeXian: string = 'BuDeXian'; + SCnPack_XiaoXia: string = 'Summer'; + SCnPack_ZiMin: string = 'ZiMin'; + SCnPack_rarnu: string = 'rarnu'; + SCnPack_dejoy: string = 'dejoy'; + SCnPack_Rain: string = 'Rain'; + SCnPack_cnwinds: string = 'cnwinds'; + + // CnCommon + SUnknowError: string = 'Unknow error'; + SErrorCode: string = 'Error code:'; + +const + SCnPack_TeamEmail = 'master@cnpack.org'; + SCnPack_ZjyEmail = 'zjy@cnpack.org'; + SCnPack_ShenloqiEmail = 'Shenloqi@hotmail.com'; + SCnPack_xiaolvEmail = 'xiaolv888@etang.com'; + SCnPack_FlierEmail = 'flier_lu@sina.com'; + SCnPack_LiuXiaoEmail = 'liuxiao@cnpack.org'; + SCnPack_PanYingEmail = 'panying@sina.com'; + SCnPack_HubdogEmail = 'hubdog@263.net'; + SCnPack_Wyb_starMail = 'wyb_star@sina.com'; + SCnPack_LicwingEmail = 'licwing@chinasystemsn.com'; + SCnPack_AlanEmail = 'BeyondStudio@163.com'; + SCnPack_GuYueChunQiuEmail = 'guyuechunqiu@cnpack.org'; + SCnPack_AimingooEmail = 'aim@263.net'; + SCnPack_QSoftEmail = 'hq.com@263.net'; + SCnPack_HospitalityEmail = 'Hospitality_ZJX@msn.com'; + SCnPack_SQuallEmail = 'squall_sa@163.com'; + SCnPack_HhhaEmail = 'Hhha@eyou.com'; + SCnPack_BetaEmail = 'beta@01cn.net'; + SCnPack_LeeonEmail = 'real-like@163.com'; + SCnPack_SuperYoyoNcEmail = 'superyoyonc@sohu.com'; + SCnPack_JohnsonZhongEmail = 'zhongs@tom.com'; + SCnPack_DragonPCEmail = 'dragonpc@21cn.com'; + SCnPack_KendlingEmail = 'kendling@21cn.com'; + SCnPack_ccRunEmail = 'info@ccrun.com'; + SCnPack_DingbaoshengEmail = 'yzdbs@msn.com'; + SCnPack_LuXiaobanEmail = 'zhouyibo2000@sina.com'; + SCnPack_SavetimeEmail = 'savetime2k@hotmail.com'; + SCnPack_solokeyEmail = 'crh611@163.com'; + SCnPack_BahamutEmail = 'fantasyfinal@126.com'; + SCnPack_SesameEmail = 'sesamehch@163.com'; + SCnPack_BuDeXianEmail = 'appleak46@yahoo.com.cn'; + SCnPack_XiaoXiaEmail = 'summercore@163.com'; + SCnPack_ZiMinEmail = '441414288@qq.com'; + SCnPack_rarnuEmail = 'rarnu@cnpack.org'; + SCnPack_dejoyEmail = 'dejoybbs@163.com'; + SCnPack_RainEmail = SCnPack_TeamEmail; // Emailÿ + SCnPack_cnwindsEmail = SCnPack_TeamEmail; + + // CnMemProf + SCnPackMemMgr = 'CnMemProf'; + SMemLeakDlgReport = 'Found %d memory leaks. [There are %d allocated before replace memory manager.]'; + SMemMgrODSReport = 'Get = %d Free = %d Realloc = %d'; + SMemMgrOverflow = 'Memory Manager''s list capability overflow, Please enlarge it!'; + SMemMgrRunTime = '%d hour(s) %d minute(s) %d second(s)'; + SOldAllocMemCount = 'There are %d allocated before replace memory manager.'; + SAppRunTime = 'Application total run time: '; + SMemSpaceCanUse = 'HeapStatus.TotalAddrSpace: %d KB'; + SUncommittedSpace = 'HeapStatus.TotalUncommitted: %d KB'; + SCommittedSpace = 'HeapStatus.TotalCommitted: %d KB'; + SFreeSpace = 'HeapStatus.TotalFree: %d KB'; + SAllocatedSpace = 'HeapStatus.TotalAllocated: %d KB'; + SAllocatedSpacePercent = 'TotalAllocated div TotalAddrSpace: %d%%'; + SFreeSmallSpace = 'HeapStatus.FreeSmall: %d KB'; + SFreeBigSpace = 'HeapStatus.FreeBig: %d KB'; + SUnusedSpace = 'HeapStatus.Unused: %d KB'; + SOverheadSpace = 'HeapStatus.Overhead: %d KB'; + SObjectCountInMemory = 'Objects count in memory: '; + SNoMemLeak = ' No memory leak.'; + SNoName = '(no name)'; + SNotAnObject = ' Not an object'; + SByte = 'Byte'; + SCommaString = ','; + SPeriodString = '.'; + +resourcestring + SCnErrorMapViewOfFile = 'MapViewOfFile Failed. '; + SCnErrorCreateFileMapping = 'CreateFileMapping Failed. '; + +function CnGetLastError: Integer; + +procedure _CnSetLastError(Err: Integer); + +implementation + +threadvar + CnErrorCode: Integer; + +function CnGetLastError: Integer; +begin + Result := CnErrorCode; +end; + +procedure _CnSetLastError(Err: Integer); +begin + CnErrorCode := Err; +end; + +end. + diff --git a/CnPack/Crypto/CnDES.dcu b/CnPack/Crypto/CnDES.dcu new file mode 100644 index 0000000000000000000000000000000000000000..86e855f0e249b9d709daafffd26601b8f2c8b4ab GIT binary patch literal 30941 zcmdUY3w%`7x$l}id(Z5dOlF2hFocH*f(FDiJc}<3Nj3$VAg{4#(GrqL2n`A3LBV6% zV2mdZr$0DXd$mWraIW@RTYGGeYo7f<+7kguiHd^Y57BOP9QE3~kkn{i6+I!F5 zGZTpT=xKDa*YkUS-}=^CJ42z9P5b>$#)k33=tolWD)Y6q=f(|x@IB_bZkso+a#d0B zH?ztsi~mx;WrMWM!~3(g71hlB&Xx_V#I<%;O>KB9rj~ivtSh)FTwPOMRr%XHZ!IpB zb9dE-PhbA7T;^YQa#h-_F zOQkMQi-EHb`~F{Pa;UPr7(x+qd6PT0s;VMfRJmyP;Z0@g((;N5foQkCxU#HvGw)J!3IGEQKYjUuN6VafoB51VndZJ!b;F!8F(9v~_Wi&9_iIblbxW$N zi*{|CvwfaFr!0_@zpIir2#CL!bl0EDJZrF=qQ)8@C-PleL}YwVVXGuxdy6 z>uJARQ0C78Tife&u9p16rMLgE%(b@s_VA6Rd}I>{iXup!d_v&($~LukH9SmWD=x0d;M+q$Y%B!WfZ#x)i; z1?tsfUI}BW!FwL0UY&Z6?+0k(xIi!$%83W3-d>hmP*ntaYlNn9f0c7}nKM6J%=z)< ztSKt52@4zMQc2DUVIZHKS5f`PAHLRG=De}GgpW?W=gNdAfG2RNRxWo;QTwciqU*=h680P!`*7#U)NkDjO79OG6@`@TDE%liGRnh8N zS(av2vxst7quKD_W0OvmjWMfP+_|cD{g9e1)8Np#MFz|8%g3mHY;@YXDj}#JQM)(G z?6~o^lmDaCwT_}j&4=ONG?e<+>5jB4T(K=&z3S_07MCXRe$jB>w{~Wh1f z+VDOC>sne>y|t+J@w(-e#U*~7>%5Ahnwl_Y+Pw}mgp0N=eE;f9xVWff!Ae$D)s#~( z*)aCTj%Wv1GCIDFj#8f{W@y#bRn=?1GJ9oNa+bAe;Uw?=;u1Bla%E9%`HnEeT;|i` zz`Cks;hi_$dds;o9}4TL^yc4Q@o+<#N^VkERa5))Z;r1nULa!eU5tIB{k#8PDqawc zwekYD&P)T@4P&jv3sgg?4ZMX_7Z)$E*g~ac1O`;2Gb#_7ZXx!2#WVbQE5Ct-;2U4n zZeF|m7Oj=BuKG9UOlK@OBdB-f7TlQk)!5Dybgo;od{u!KGyRO1o;~9d`-ntPE)QmD ze4R0M3!XN-{rm3A*{ncJPcvh?E@9uwoaI@^r+hWM3r!D98h^vASw7K}TUS~du14!E zfnTniJxdj>%Xgq<`0-XL;6o8ic!r}yC}WQni2(@rKqJ}tAh=mZf`Lp1-b(_$Q%AzZj-16GxtFUlf z^PG!U@~Cp%bM7l#=+Sm=Lv8VMD(_lVh)T|LNms}aBIPaQ!Mizh08qGB(Y%yfVM2wg?ke07}*-#tM4V-AF6+)|LI~j^zZduQ+oY5}O^! zrNS2iwMqxI#s+Gg1(XYNKt4l^q}T`n0XONh*Y{0x-&j|x6LQNS$b)Ha2+WKP#gQKJZ&0`f{@mh6A=$dF#Zh3T5u|z%YaZw(^UD`B2ww2bVo5Y4nefnOH+q4 z$65%;+gw#u6P`oRGGbXO(dj6)v9wudX^VxWc!+ZoLafjsR@xwL(;-${AbRq46;~jD z^N7#(*+>I3wK||3y&3LJ<+U`9Sp2goqAgb>p`B9GilXB1QpR?&2glqeJs=H#^PvZ% zOm|_?H^ajA+4B(MGWO89Y0C0SG(nfQ>(K8QoaTZq(Fow*?iZ?T2&Q{<1us~L_B&rm zcVWcbMHQ&r^=rLSjmq7>rt59h^tkd>Hai+q3mL&8t$8Fd%P`B!+?-`utULyPx zt>4vg?@2d}>vG2aDOFH(Z!n$6r0~kv_fDicMd|)yI>wITOg9{#Op6rJM8cTPqz+Aa6U0xU7O2Oh^dJQ`MrKdR4r^|au zMR^%_Zhz!F;@=bXnpDn5ljQwSJ-eqhB4_6387)U5ZFM%1d zc$hp0&$`+GWh^3~}$t~bBrAEZtC#*EQ zpwpmBByUr(kjPhdKJH?VD={=k%XdJq>Yzn5{f1~RM@R4zh{kmjw#ZdvHd&9Fa@w!U z>3%DX2kdgP)A(Vm);>2HrFAzEvG?mF?y-`%7bH$ZJ}nkWVS*vrO>na$kLJ#lLH0lf zH8jnMp#bNyn169*N~~@2^ce=abWZJR=8+`X#iB5{sdDqYEV??o`qRDS-sW=cf;U|P zxHc;zUqU`^Kt9OE;e~r41THQ{|IHf)RX= zsEBIDM#a`ImWpTuFsN7_d43;z#}y+B;a_P+4B&DwgaS>bU33f(654NdtDnNHEE0kh z*l3&L{-S8RknfL+8WTJSJ8dm57uJ;XRPZk5@JNnyEatAYRdv7rOYAA?M4A< z3=yW=R~%u_yZ*+6=_V%#%gfD!#2)_VvT^L?(M!xr8xXOQOha%^9i<2@i%)x0p0<^- z)0F3j5hX)L)Z;7D&@}0*glX0w3WQ`s5+;Bb@2DfL+4C@X`>;`Oe%YeGp|@zUB0a%3{UvXGsatV*)MW@ zY*cCXqTL@ATj-CjMDR&?BhQPc#Abn?HT@#+?=k4&RPVJ@J;qM;UK`cXl}k{~bJq`J zrT*#i!t;pV5=)v*T{P&rc<-Ezts*;Hul?2N<;p0sv85}+p6)LA+pwjtf8a(a>oq%D ztL<#PU}tMJ*qW5sM~sw_=eK+1i_34#{j953Cl9;XDJDXjQAblqj`E@s-#A_pq`#db z@-jkZ8k@9_j;YTfFHSWD7ma2{*2S~qBe5A_bWi^Yvg7kO)WyYvDBV$o+vtAezdGH~ zIA+kzGw>AkGtF|(BY0aR6Iy660u+zR+wFe-p54#4!_VWi5Sz0v_}g&vsRP)=ShujI z(|w1r|t|PgRZULUKZ2|U2lfCE4op&7>( zCS$ta#4%Q{{+%laK)WZ0mMyt`z&x3L6E(Tej*wgS`OhZ%-F^SU>d*tb~N1i3PKN0*RG0{se zKoUOv?FD`}g?yIYNML>`W6v^H{E(C>Zk*B1e}YnmO6})nP5K9MgM=QD|JK+ihPI={kH#xe(%-lDcMHmxz0WgnE!F?q%fthgXQc!;qdNChi`hZ%cR zD##5!&Ddj7!P4vw#(pg2)6}^E;BE-ug{1H7&nuN)VaIVvD4lf{!n0n0&8J2e0zJ9M}JccqLyjfRbQc1St+jq5jdj(!u~ zAy9vAe*p`k;Ta60jy2SQR6p9&rT46-o{2^ejom;k8P=AK)H26tAu^uTXO~jX%|;K+ z-a;)!)|N_Y*=}vArj}jSmL1g6Vzi_KPPdNX4(d5z^bm%Ig=qPq(c(wTFEN&=I;KB= zg(tQ5=rHaf7|$6q2*w_2dBNIpFSWdEwD>UQ*O*N*Jg!4|kVbrHj36lcsReoxQY8vr zlGazKQv-Ir*rQ6K5#byaObmMu&KwD{cMkgd9 z#bu70YLs&BLCLoX8ssCxFe|<}QCbgCS$|}`vQd9x^U5ac z<%@ktEcW#Z!s3o?jFKV(2BCw}Kq_O&(f2S&x%8nQa#f7sBW$l_j5Nr6OJk$~mX|hC z0h>PbqazX(@tY$xUn+2+kv{Zep~`8#XTTfzFN`qWRWROB5De>#7%wAi#6bGc56OZ5 zNbKr4GczWR@i?xXcjaZ1#w9tgUvSloDJjXy4PXA!6_;KTa4*WvOivA}?3%f=rlpPb zO4rSwJ$>?cpS*Zs*5y+t_+3}HzZCfLB{y7pxhu=RaKhrLGnA{67o=Q2Wx71uH-G$f zlP_~#nKWM@=ZQBK2W z5%%a=9_w@9{E^-{lM_j%1%Z zNtV=PH}g1Umse61zb`4^NOs8{HQ;1P4#}r@{ceXhnYlcwTMqc0Ns8oiC;Odf@H#Ld z$tMGTlHv+5r|gz|4lm%lJj|Em2Axj7BB`=7z+7HOvg(mB+%5SfpX_jZlU%Ce3?wtZ z$Df22H|S*nuhXNtWXX}_O?ImRk56$qnLkPOxg8J?aCp43;sla_M{=nw*(v)W6)$*m z`#g%vk?dzlPSxWN0IkpIW-`zwxn!q=-hemB?{K@Ank*+t{s5j%$XD@V7E5wNzFxmm z@ks&I<&cw-G28DA0EYrhNy(~1_PRYF&@VZC$>7NqNOE{R;E#belCaY)gW4ppBSEMR zkIyfG>*Rn_L5k*g%U(4Z`eaUwG5p8yGsBO_-wYoze9rJK^26ky_Yx*cll;nf&xEl_ z&WY}TD{Y+5kvVVb^sI$bu9!PJ{YzJ7U;gEc`B%-HbJ^reLu~_%U1wTCLoM3JZQ94z zYD4uZo-Nv$w_R--TF~1Fq{Y_t6XfSZ_pHO6-r=4wu9|sPOA9L9=wNo*xvCkbh7K7CMlrzKV ztsl&(`=2_7j{&BwaIm!?`AoAfD0DqP(hI@hcXw`%96r?-aAHM~A`_v>U#FP!#1 z!|RUD*JbZB&DzKFI$H7T*R7%9&exrh@h_5aT4iZ^pjkWHs-3-AH`rK_lTm(3hDRy& zMRf;kQon%eKe^yXNk_Jgj)CUFzX~5F0seJaQ%B&QyCIVtc<@o}3`r3>YGuxjwh)|j zjid9l+xra4%@VceIE)U-?8tTS9?9r&Mtj5@C+}$;+wgi&XtVP)bVx9BotWB?9)OVy z7Y^1nks~`C68|wC+-Q4S3iTMZ#T6-h2eaBjL%JSYwRbxE;ra`@Fpj8_ryLqEkd#_nL)vCSUti9Q)ebB7+Q{3ro(|TK*Niq@b ztwWSwaKx6@H=?br+FLsG(>nB5TeZ`A)7yH}f3#|E>rDfCQ(vn#fF`f@Mzi)>t9Ghc zd%abAvswE?tJdGFo!p`TT|~}-^F(~P5$)Az>=@R18|!<6fu<0)l@^QZi;7H%6uxT{ zS&P<3Q9abxDhKg9J3r;!VXd#RzRy+nCfUWio&6G*#Jkg-I-!RAAecW+4|MiPBxgv_ zMc&v?61)K_pvmv?$q@Z}=H&NvE+PE)&B-6=lOg^OX!1KGY{&s?MPKW>lv6^=p}yw) zlv9E_weB@OrcLW}cC_Xzr$8G9JAduXPk9psjMVv%>wXu}-aSM~pl&6cWgiB$74{+c zyvu_Ru`GhmGd>X=n{WDB+xwCF=G9M8Quo0lHzQ;tAQ4&wuOY~vi_C`*)+~EPa8v8v zXwv{%<)|9!hgqQMFPP0I(J!ox=pN)V2SMb3Sh;}N+M6E)GXOlu0n@@K*Fo_St$)=P z_{kZlKT@DITTtn<2O)|9z@M9+(yv3v_sRy2{}4pNK(@m`;t<;CIc4o8)8OP-fSt4q z5DW2uxe$Y$xA=Cve%KLcqELc>LTR*R&fiJ|g|y5Je-R?EsOKBEkvnq3S}n4xHerp8 zLu!4-+d;VGp=FSdFm#@NMF-sR8kR7|PRb7cGQF{7Lo_5 zGw;oCgt*FW{AT_uzpq!vSDp#xNx9ufWkZv>w40ORmhG3vxaUKOZe`tZ7|!l z^M2QIYjhC+P~ELVn`eNElHu%>?c}O0?nvQ4tmUySr)u+YJ6zQN4kIv7!=!jKnfeFk+Y&>#d#n4PgHGQLUFq zfOt3`LlIdTnQ;RAghOXsOo(T^cewC)-M^ZQ4*+@`!|$5>ZU#thAUz4WzBPe?^g!I4 zhKSa~pN;iB+(1+q$VtwON(S<>1#_H?2(L{>kNT#SNi(=W+PjjdO7 zo6T(w0T&TTt@mJ^RKd~PDF{n(v5?Y^dCwX4YKG21Zt>XO=s@Rngf{O05aHhdq?`4} ztoABcjS&VS+92;}>qhQDKOkut0k49@#$9Kj-0G9Roty3J2Py#&C zdZe?34uNz_LEtkgv@VXgG{l%LF_|z$NVJgLc2Nt78Tj;tq-|_W=)>lSmXgO!6Z;1D z(IFv)r|96AGij>$59X?pa1}L#Ng`e~8WF$BMf`Ut+SoPv!lM1!s6|_mXcaL;Yd9&1 z_$L+-8*2htv1+yA`5dq49=#P44fa(?J09x*dUWg->$>m;J%q&Dx|-0|4XTa&7V`r4 z+zF$Ay&pTO^`L~6tY?Ik>_Uq_F=6_E0HVezDt`Iz87@3l*JAp_&xHVWpD+(NY(8<` z1R#;>4vj{2IUMt7y(2zx_~KOdJ)yEMCizIL!UX9@oi+XF`~+$=Qs#YBXxYadav$wU zTK3uE9y#G$L`jiVG}aHXy3{Rf3rtpD9I$%~4v%fohTfiwHY&H_yi9an+1qj}R*s=- zwG(uwfX!Yn-6@<9M{1Zu@B(+$gKk<^b^<+|Kf2#Sw;H(f2avq6ogfsc!)tvw%)!Zx zT60C@J|efByhykwU!8vDIAFH$W?RNgcyy30X@IvJOa&ro|f}xh#Dfo6-ZOZj#1mfMVs2FOd`(I zjNQh_rZy^*u$!8xvLBPvHxY#B8FXTmZ8TIyg_eDMCuenk>qcVpr*V1O17E8h*ImAc zT>dzYNU+M8F8^El4d_$t|Hi|B0C+|?6yJPB0{|U*^8hd^=^^UO(FWj! zbF@L5hDfI)1_KkvsN4u?vTd6k)!1Sn5y1hkh*2=J1qZ~-UOhOFQmpPu^*DD;92`C+ zhh!91%v6uVY+79v4-_67f#Mjqw`01!b(6gv z!|4jP@}|AvuRLvmVpMXDH&8Nz1O|FAp@H_`NJ*`k6uB=(v`tj!@th}SBOO!_E;9#* z@t)+y+aJGTnRrOT78N#8T`Y>^e^`inX?ZhOtQF`s75YmaMrg)}VT3CbyMFV;!C2;b zq7D%lCl6xrZyZXkpZs<*j*|{`qf;lu?7PFbYM?89ek(8}Za%P8#x2*!t@)Ch&JFl& zNVF|Ln`z4piCXvXCJ#R+HR!2_83Og=mqh32ja?^j*)tfaKe75L7v_q~o|X`O8{4l5Ps5tf4FWUzaN{h07yR=%gfyVlQ)cS>6Qo%yP zoy0)n&?VoQz)#;vX5u`ZZi!Os_{|xP5#nXZTk?Z~RJvHw2jvHGxf3JF|7%L}w?dMZ zO_nLoe#>#zs7~+qpVJR#yAz7y4%71^+ObuU!s9WA4dg7gZ5k~Uj5i*SW{T8EhyWwn z7(om$uK~Kb0XEimo7Vsois8)9;*|Gac~J~WeCXJ5RO`YZ*q0d97V3&WtF($0Y9MzuDgH+ zC|1U4Ku)9qLSfSYe1?lXMy7ipNNj&&_fqG-Hz42^xta1LN-T0VFIb3dGk)qP#c}c! zhq(X1LFk9Ld0d_%PMKC8y=%B1Wbl*Mj)cN|;sU~4&*f&hQzFY9;&O{IXF_BXW<N&+cYsHMisPPKo#vrHN3P=h9pL{g$~D? zcSP$luOhk=T}2Rc7FC!kBK|C@GgU+^nkIjEgsY1#TTV5s9Ud-h4>YZ{s_cJrl?lod zyMS?eaW60?)LX*^^tLXM-p+6p#psPt*!32tiG*iD6kec-Cy#1;4R6!hM>rD-9Ul31 zgOFP!ZEAohwP?oF0I{Wy*R{)UL%4SNZHOQu{x$?!IUF^vVXb|*@X0{aSFBq3$B`V# zI6&{^e$>};>tM^R(RGrti4PzPu|8Uk(TxLf`^|-MqOV_G;CSthZ4l$hqZ*Gq5v>o$ z(1UHE{=h*Q+xy;UwG;4--g(cp`#_(_Np8>Y+^|M-sdPbwJv17Hi5EdWV}%)J^TjLbvqwfL`_p~m??Hb4n;RLvT= z-OwBUmSt2opL<{o{3MeKE&I4_?4vDA%RaKsmckD4M>G@^er4JN9s7R5D>Iy2;{3c@ zKhNx<^Guv%!jZeo^UR5y?mnEC;6M-uKONk~DN4|>19CEZ=%7pnuMyiD#d%3zw2@zA z-T4x`|7aH$>#*M0(z&4dvD z=g&2no|QVP$5Cg7x);exnrO_3r}X@oa(5ST$!+_*Rz2o(w(3m?kg$F8I&W0AMmxMO z-VH`&el|BCv$m{kHaD=ihv^37$i~)uWH%UpG>=qn9t2^;Gk@JYnho=yLd(8; z_-{)XENqX4J{e1@SPCy9^mXvi*P(~L!xZ{DkZ!bTht1G;BdFGIX1e*+Azt>3T0pxQ z2*pWTOduQr<#B{YKm=N> z#Iy#YQMZ!#plH%Gs_+mAbt5`Q4{xH@;WvZiX~DZKNYVnN2T3vjYZ#(>To_6mB)?#Z zkil9hrFtBtrbi^fb|XzRX2gK0Uu)ilF+5;Wp=F=NFAATC`ofn!O~7pDzR<4w!jt3+ z?KmH7)1EYafle*00drJ(8QFQBFr8-=PZ(mHXArE$IS-j!0_QoE(0L9w)*t3qqA_aW zBIn2>p$@#~9yLyz(-1C;bC^y;ge3~0#DzYdn_UlgMBFgNW)&t~q)m&tG*O+?#p4hX zGo)b0q7IV=1g7yU3?M=-UVAC;G3W zV5_lpCcdoTAd?TK%k4q=Apif{D*kv}_Nnq6s_a+gpem152`JgJ-X0k&}K9nV^6WC!UAD&Nzr=eGBrhgkdy^#&9VP~?G*^}j0 z7t606WaoIfZ?W8Wkd2Y%E3>D{uP>Bezmv_Bc+bhj^2vkjdg*rg)O5C*227Uw7t8&3 zvT{*5y;wedC)+LUlh}PyI(tA`sH~QH<@=;GWw$g|f1Xszr7YHozA@5ICFOeQyUI*y z6?;p%TRHQR(kUg&__bY9&ZV*xXPS~dRZhVdDJ(?kIyS|bCQs38YuF6uROOnTa=FK= zEZ)SfcCKKWbCI$vC~MBiN{VxWvLdKVaV}Nz)0Es<$^%kR$<9~uXDPYa%3D%4+AuJv z6!8C7PGDP|vuW~HJ~?QeRce{CRZLkqp6wOL_9jM_uH*t=0mrvq;6u|ad2bYD8tW7& zJ7Z9axs^&T3PkIAUYaX+>bO(cd(Lzvd$Y18h_4!+D?8-LO2IVcJ#>Rt4N|*54UGn4 zDHxI>PgA}>!5Fd?a!fJ%XQF?m1;kioU7E62K$)qJN@GhfYKa93AJqv!OUxlR%d?f6 zg7{y)8Q`u-B=TZIgQO!ZjxszItsa)!#XIylddj|aUrG~z(UF#6P$) zSI)rXXt-MKN<)hg&K3ap0s}aYLOS_?zrYHgDgyq3DEv|u0{oB#J_m6GC_*}lG`7`k z1hTE}Xduf{j@YytL|}`J6NXIaiFh$r-s-l-v;!vK1Lp;74?b}~57>adXaFT!eet|- zEs;2uatpzKJ%q^>$W>+4 z=P38=VS8OtHIw!&l4}1nh5a|ie(F`SYQsBg<(~&#S@@UUcuC1B!9TwwzZ{gaHr3R~ z58zo_f#>+2eg7aXf7t+Q$K&!_*daW!^4VcL=C5E+<8e(c>%b#tDSH-Q(7jY;-KgPl z438Bm>%n8C%6jowlgnPgV|^(*fyZsj*sDnSOOPbvQQE*>N8@HnmQme;gc*+tN}BPk zMB4;7)tLrw<_!al{EPs7jhqzelAaOv$Is1p*TE9C{Q|} zJnv#5Dmh#)dsqvVcDpn;>!i|)t~pMuuPB{$(IQL3+;vW@r6|pG(}Ie^RqhNITTP{U z_Y?(d97_N0{?LU53Z)cvfeY&lN=52k{8M>U`k{J~Eug~lYA4Rfs5H^@5u!N?OFWo% zfJ%>e9&xc3sib&QR75qD>b(n8wwg+R@@`LJd#Myjs#n +================================================================================ +* ƣ +* ԪƣDES ԳƼӽ㷨ʵֵԪ +* ԪߣCnPack (master@cnpack.org) +* /ֲ䲿ֹܡ +* עԪʵ DES/3DES ԳƼӽ㷨ֿС 8 ֽڣʵ +* ECB/CBC ģʽ֧ģʽ +* +* ƽ̨PWin2000Pro + Delphi 5.0 +* ݲԣPWin9X/2000/XP + Delphi 5/6 +* õԪеַϱػʽ +* ޸ļ¼2024.11.30 V1.7 +* ɾ淶 DESEncryptStrToHex DESDecryptStrToHex +* ɾ淶 TripleDESEncryptStrToHex TripleDESDecryptStrToHex +* ECB 汾 +* Ż PAnsiChar ʽ Iv Ĵ +* 2024.10.12 V1.6 +* 3DES ²Խ⣬Ż Key Iv Ķ봦 +* 2022.08.13 V1.5 +* Կݼܷؿ +* 2021.02.07 V1.4 +* Ӷ TBytes ֧ +* 2020.03.25 V1.3 +* 3DES ֧ +* 2020.03.24 V1.2 +* ECB/CBC ַӽܺɾԭеַܺ +* 2019.04.15 V1.1 +* ֧ Win32/Win64/MacOS +* 2008.05.30 V1.0 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative; + +const + CN_DES_KEYSIZE = 8; + {* DES Կȣ8 ֽ} + + CN_DES_BLOCKSIZE = 8; + {* DES ļܿ鳤ȣ8 ֽ} + + CN_TRIPLE_DES_KEYSIZE = CN_DES_KEYSIZE * 3; + {* 3DES Կȣ DES 24 ֽ} + + CN_TRIPLE_DES_BLOCKSIZE = CN_DES_BLOCKSIZE; + {* 3DES ļܿ鳤ȣ 8 ֽ} + +type + ECnDESException = class(Exception); + {* DES 쳣} + + TCnDESKey = array[0..CN_DES_KEYSIZE - 1] of Byte; + {* DES ļ Key8 ֽ} + + TCnDESBuffer = array[0..CN_DES_BLOCKSIZE - 1] of Byte; + {* DES ļܿ飬8 ֽ} + + TCnDESIv = array[0..CN_DES_BLOCKSIZE - 1] of Byte; + {* DES CBC ijʼ8 ֽ} + + TCn3DESKey = array[0..CN_TRIPLE_DES_KEYSIZE - 1] of Byte; + {* 3DES Կȣ DES 24 ֽ} + + TCn3DESBuffer = TCnDESBuffer; + {* 3DES ļܿ飬 DES ļܿ飬8 ֽ} + + TCn3DESIv = TCnDESIv; + {* 3DES CBC ijʼ DES CBC ijʼ8 ֽ} + +// ================================= DES ======================================= + +function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +{* ֽڳȼ DES ȡǿ + + + InputByteLength: Integer - ֽڳ + + ֵInteger - DES ij +} + +procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString DES ܣʹ ECB ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString DES ܣʹ ECB ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; + Output: PAnsiChar); +{* AnsiString DES ܣʹ CBC ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; const Input: AnsiString; + Output: PAnsiChar); +{* AnsiString DES ܣʹ CBC ģʽ + + + Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +function DESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; +{* KeyDES ܷתʮƵģʹ ECB ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + + ֵAnsiString - ؼܺʮַ +} + +function DESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; +{* ʮƵ KeyDES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + + ֵAnsiString - ؽַܺ +} + +function DESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; const Iv: AnsiString): AnsiString; +{* Key IvDES ܷתʮƵģʹ CBC ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؼܺʮַ +} + +function DESDecryptCbcStrFromHex(const HexStr: AnsiString; const Key: AnsiString; + const Iv: AnsiString): AnsiString; +{* ʮƵ Key IvDES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 8 ֽ DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؽַܺ +} + +function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ ECB ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؼֽܺ +} + +function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ ECB ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؽֽܺ +} + +function DESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ CBC ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؼֽܺ +} + +function DESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ DES ܣʹ CBC ģʽ + + + Key: TBytes - 8 ֽ DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؽֽܺ +} + +procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +{* DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + Dest: TStream - + + ֵޣ +} + +procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +{* DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + Dest: TStream - + + ֵޣ +} + +procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 8 ֽ DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +// =========================== 3-DES (Triple DES) ============================== + +function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +{* ֽڳȼȡǿ + + + InputByteLength: Integer - ֽڳ + + ֵInteger - 3DES ֽڳ +} + +procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ ECB ģʽ + + + Key: AnsiString - 24ֽ 3DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ ECB ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ CBC ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +{* AnsiString 3DES ܣʹ CBC ģʽ + + + Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + Iv: PAnsiChar - 8 ֽڳʼעЧݱڻ 8 ֽ + const Input: AnsiString - ַܵ䳤粻 8 ʱᱻ #0 ȴﵽ 8 ı + Output: PAnsiChar - 䳤ȱڻ (((Length(Input) - 1) div 8) + 1) * 8 + + ֵޣ +} + +function TripleDESEncryptEcbStrToHex(const Str: AnsiString; const Key: AnsiString): AnsiString; +{* Key3DES ܷתʮƵģʹ ECB ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + + ֵAnsiString - ؼܺʮַ +} + +function TripleDESDecryptEcbStrFromHex(const HexStr: AnsiString; const Key: AnsiString): AnsiString; +{* ʮƵ Key3DES ܷģʹ ECB ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + + ֵAnsiString - ؽַܺ +} + +function TripleDESEncryptCbcStrToHex(const Str: AnsiString; const Key: AnsiString; + const Iv: AnsiString): AnsiString; +{* Key Iv3DES ܷתʮƵģʹ CBC ģʽĩβܲ #0 + + + const Str: AnsiString - ַܵ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؼܺʮַ +} + +function TripleDESDecryptCbcStrFromHex(const HexStr: AnsiString; + const Key: AnsiString; const Iv: AnsiString): AnsiString; +{* ʮƵ Key Iv3DES ܷģʹ CBC ģʽ + + + const HexStr: AnsiString - ܵʮַ + const Key: AnsiString - 24 ֽ 3DES Կ̫ضϣ #0 + const Iv: AnsiString - 8 ֽڳʼ + + ֵAnsiString - ؽַܺ +} + +function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ ECB ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؼֽܺ +} + +function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ ECB ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Input: TBytes - ֽܵ飬䳤粻 8 ʱᱻ 0 ȴﵽ 8 ı + + ֵTBytes - ؽֽܺ +} + +function TripleDESEncryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ CBC ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؼֽܺ +} + +function TripleDESDecryptCbcBytes(Key: TBytes; Iv: TBytes; Input: TBytes): TBytes; +{* ֽ 3DES ܣʹ CBC ģʽ + + + Key: TBytes - 24 ֽ 3DES Կ̫ضϣ 0 + Iv: TBytes - 8 ֽڳʼ̫ضϣ 0 + Input: TBytes - ֽܵ + + ֵTBytes - ؽֽܺ +} + +procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +{* 3DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 24 ֽ 3DES Կ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +{* 3DES ܣʹ ECB ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCnDESKey - 24 ֽ 3DES Կ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* 3DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCn3DESKey - 24 ֽ 3DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +{* 3DES ܣʹ CBC ģʽ + Count Ϊ 0 ʾͷֻ Stream ǰλ Count ֽ + + + Source: TStream - ܵ + Count: Cardinal - ǰλĴֽܵڳȣΪ 0ʾͷ + const Key: TCn3DESKey - 24 ֽ 3DES Կ + const InitVector: TCnDESIv - 8 ֽڳʼ + Dest: TStream - + + ֵޣ +} + +implementation + +resourcestring + SCnErrorDESInvalidInBufSize = 'Invalid Buffer Size for Decryption'; + SCnErrorDESReadError = 'Stream Read Error'; + SCnErrorDESWriteError = 'Stream Write Error'; + +type + TKeyByte = array[0..5] of Byte; + TDesMode = (dmEncry, dmDecry); + TSubKey = array[0..15] of TKeyByte; + +const + BitIP: array[0..63] of Byte = + (57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7, + 56, 48, 40, 32, 24, 16, 8, 0, + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6); + + BitCP: array[0..63] of Byte = + (39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25, + 32, 0, 40, 8, 48, 16, 56, 24); + + BitExp: array[0..47] of Integer = + (31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, + 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, + 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0); + + BitPM: array[0..31] of Byte = + (15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, + 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24); + + sBox: array[0..7] of array[0..63] of Byte = + ((14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13), + + (15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9), + + (10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12), + + (7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14), + + (2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3), + + (12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13), + + (4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12), + + (13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)); + + BitPMC1: array[0..55] of Byte = + (56, 48, 40, 32, 24, 16, 8, + 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, + 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, + 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, + 20, 12, 4, 27, 19, 11, 3); + + BitPMC2: array[0..47] of Byte = + (13, 16, 10, 23, 0, 4, + 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, + 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, + 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, + 45, 41, 49, 35, 28, 31); + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +procedure InitPermutation(var InData: array of Byte); +var + NewData: array[0..7] of Byte; + I: Integer; +begin + FillChar(NewData, 8, 0); + for I := 0 to 63 do + if (InData[BitIP[I] shr 3] and (1 shl (7 - (BitIP[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 7 do InData[I] := NewData[I]; +end; + +procedure ConversePermutation(var InData: array of Byte); +var + NewData: array[0..7] of Byte; + I: Integer; +begin + FillChar(NewData, 8, 0); + for I := 0 to 63 do + if (InData[BitCP[I] shr 3] and (1 shl (7 - (BitCP[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 7 do InData[I] := NewData[I]; +end; + +procedure Expand(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 6, 0); + for I := 0 to 47 do + if (InData[BitExp[I] shr 3] and (1 shl (7 - (BitExp[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure Permutation(var InData: array of Byte); +var + NewData: array[0..3] of Byte; + I: Integer; +begin + FillChar(NewData, 4, 0); + for I := 0 to 31 do + if (InData[BitPM[I] shr 3] and (1 shl (7 - (BitPM[I] and $07)))) <> 0 then + NewData[I shr 3] := NewData[I shr 3] or (1 shl (7 - (I and $07))); + for I := 0 to 3 do InData[I] := NewData[I]; +end; + +function Si(S, InByte: Byte): Byte; +var + c: Byte; +begin + c := (InByte and $20) or ((InByte and $1E) shr 1) or + ((InByte and $01) shl 4); + Result := (sBox[S][c] and $0F); +end; + +procedure PermutationChoose1(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 7, 0); + for I := 0 to 55 do + if (InData[BitPMC1[I] shr 3] and (1 shl (7 - (BitPMC1[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure PermutationChoose2(const InData: array of Byte; var OutData: array of Byte); +var + I: Integer; +begin + FillChar(OutData, 6, 0); + for I := 0 to 47 do + if (InData[BitPMC2[I] shr 3] and (1 shl (7 - (BitPMC2[I] and $07)))) <> 0 then + OutData[I shr 3] := OutData[I shr 3] or (1 shl (7 - (I and $07))); +end; + +procedure CycleMove(var InData: array of Byte; bitMove: Byte); +var + I: Integer; +begin + for I := 0 to bitMove - 1 do + begin + InData[0] := (InData[0] shl 1) or (InData[1] shr 7); + InData[1] := (InData[1] shl 1) or (InData[2] shr 7); + InData[2] := (InData[2] shl 1) or (InData[3] shr 7); + InData[3] := (InData[3] shl 1) or ((InData[0] and $10) shr 4); + InData[0] := (InData[0] and $0F); + end; +end; + +procedure MakeKey(const InKey: array of Byte; var OutKey: array of TKeyByte); +const + bitDisplace: array[0..15] of Byte = + (1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); +var + OutData56: array[0..6] of Byte; + Key28l: array[0..3] of Byte; + Key28r: array[0..3] of Byte; + Key56o: array[0..6] of Byte; + I: Integer; +begin + PermutationChoose1(InKey, OutData56); + Key28l[0] := OutData56[0] shr 4; + Key28l[1] := (OutData56[0] shl 4) or (OutData56[1] shr 4); + Key28l[2] := (OutData56[1] shl 4) or (OutData56[2] shr 4); + Key28l[3] := (OutData56[2] shl 4) or (OutData56[3] shr 4); + Key28r[0] := OutData56[3] and $0F; + Key28r[1] := OutData56[4]; + Key28r[2] := OutData56[5]; + Key28r[3] := OutData56[6]; + for I := 0 to 15 do + begin + CycleMove(Key28l, bitDisplace[I]); + CycleMove(Key28r, bitDisplace[I]); + Key56o[0] := (Key28l[0] shl 4) or (Key28l[1] shr 4); + Key56o[1] := (Key28l[1] shl 4) or (Key28l[2] shr 4); + Key56o[2] := (Key28l[2] shl 4) or (Key28l[3] shr 4); + Key56o[3] := (Key28l[3] shl 4) or (Key28r[0]); + Key56o[4] := Key28r[1]; + Key56o[5] := Key28r[2]; + Key56o[6] := Key28r[3]; + PermutationChoose2(Key56o, OutKey[I]); + end; +end; + +procedure Encry(const InData, ASubKey: array of Byte; var OutData: array of Byte); +var + OutBuf: array[0..5] of Byte; + Buf: array[0..7] of Byte; + I: Integer; +begin + Expand(InData, OutBuf); + for I := 0 to 5 do OutBuf[I] := OutBuf[I] xor ASubKey[I]; + Buf[0] := OutBuf[0] shr 2; + Buf[1] := ((OutBuf[0] and $03) shl 4) or (OutBuf[1] shr 4); + Buf[2] := ((OutBuf[1] and $0F) shl 2) or (OutBuf[2] shr 6); + Buf[3] := OutBuf[2] and $3F; + Buf[4] := OutBuf[3] shr 2; + Buf[5] := ((OutBuf[3] and $03) shl 4) or (OutBuf[4] shr 4); + Buf[6] := ((OutBuf[4] and $0F) shl 2) or (OutBuf[5] shr 6); + Buf[7] := OutBuf[5] and $3F; + for I := 0 to 7 do Buf[I] := si(I, Buf[I]); + for I := 0 to 3 do OutBuf[I] := (Buf[I * 2] shl 4) or Buf[I * 2 + 1]; + Permutation(OutBuf); + for I := 0 to 3 do OutData[I] := OutBuf[I]; +end; + +// InData OutData Ҫ 8 ֽ +procedure DesData(DesMode: TDesMode; SubKey: TSubKey; const InData: array of Byte; + var OutData: array of Byte); +var + I, J: Integer; + Temp, Buf: array[0..3] of Byte; +begin + for I := 0 to 7 do OutData[I] := InData[I]; + InitPermutation(OutData); + if DesMode = dmEncry then + begin + for I := 0 to 15 do + begin + for J := 0 to 3 do Temp[J] := OutData[J]; + for J := 0 to 3 do OutData[J] := OutData[J + 4]; + Encry(OutData, SubKey[I], Buf); + for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; + end; + for J := 0 to 3 do Temp[J] := OutData[J + 4]; + for J := 0 to 3 do OutData[J + 4] := OutData[J]; + for J := 0 to 3 do OutData[J] := Temp[J]; + end + else if DesMode = dmDecry then + begin + for I := 15 downto 0 do + begin + for J := 0 to 3 do Temp[J] := OutData[J]; + for J := 0 to 3 do OutData[J] := OutData[J + 4]; + Encry(OutData, SubKey[I], Buf); + for J := 0 to 3 do OutData[J + 4] := Temp[J] xor Buf[J]; + end; + for J := 0 to 3 do Temp[J] := OutData[J + 4]; + for J := 0 to 3 do OutData[J + 4] := OutData[J]; + for J := 0 to 3 do OutData[J] := Temp[J]; + end; + ConversePermutation(OutData); +end; + +// Key #0 ճ 8 ֽ +procedure MakeKeyAlign(var Key: AnsiString); +begin + if Length(Key) < CN_DES_KEYSIZE then + while Length(Key) < CN_DES_KEYSIZE do + Key := Key + Chr(0); +end; + +// ַ #0 ճ 8 ıעմ +procedure MakeInputAlign(var Str: AnsiString); +begin + while Length(Str) mod CN_DES_KEYSIZE <> 0 do + Str := Str + Chr(0); +end; + +// ֽ鲹 0 ճ 8 ıע鲻 +procedure MakeInputBytesAlign(var Input: TBytes); +var + I, Len, NL: Integer; +begin + Len := Length(Input); + if Len mod CN_DES_BLOCKSIZE <> 0 then + begin + NL := ((Len div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; + SetLength(Input, NL); + for I := Len to NL - 1 do + Input[I] := 0; + end; +end; + +function DESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +begin + Result := (((InputByteLength - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; +end; + +procedure DESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Str: AnsiString; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + + Str := Input; + MakeInputAlign(Str); // Str 8 ı + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +procedure DESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmDecry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure DESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector: TCnDESIv; + Str: AnsiString; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure DESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + MakeKeyAlign(Key); + Move(Key[1], KeyByte[0], SizeOf(TCnDESKey)); + + MakeKey(KeyByte, SubKey); + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure SetResultLengthUsingInput(const Str: AnsiString; var Res: AnsiString); +var + Len: Integer; +begin + Len := Length(Str); + if Len < CN_DES_BLOCKSIZE then + Len := CN_DES_BLOCKSIZE + else + Len := (((Len - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE; + SetLength(Res, Len); +end; + +function DESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; +var + TempResult: AnsiString; +begin + Result := ''; + if Str = '' then + Exit; + + SetResultLengthUsingInput(Str, TempResult); + DESEncryptEcbStr(Key, Str, @TempResult[1]); + Result := AnsiStrToHex(TempResult); +end; + +function DESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + DESDecryptEcbStr(Key, Str, @(Result[1])); +end; + +function DESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; +var + TempResult: AnsiString; +begin + Result := ''; + if Str = '' then + Exit; + + SetResultLengthUsingInput(Str, TempResult); + DESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); + Result := AnsiStrToHex(TempResult); +end; + +function DESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + DESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); +end; + +function DESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + MakeInputBytesAlign(Input); + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function DESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + DesData(dmDecry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function DESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + MakeInputBytesAlign(Input); + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey, StrByte, OutByte); + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +function DESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + KeyByte: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + FillChar(KeyByte[0], SizeOf(TCnDESKey), 0); + MoveMost(Key[0], KeyByte[0], Length(Key), SizeOf(TCnDESKey)); + MakeKey(KeyByte, SubKey); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure DESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + MakeKey(Key, SubKey); + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then // β 0 + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure DESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + MakeKey(Key, SubKey); + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmDecry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure DESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Vector: TCnDESIv; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Vector := InitVector; + MakeKey(Key, SubKey); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure DESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCnDESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + TempIn, TempOut: TCnDESBuffer; + Vector1, Vector2: TCnDESIv; + Done: Cardinal; + SubKey: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Vector1 := InitVector; + MakeKey(Key, SubKey); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorDESReadError); + + Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); + DesData(dmDecry, SubKey, TempIn, TempOut); + + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorDESWriteError); + + Vector1 := Vector2; + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure Make3DESKeys(Keys: AnsiString; var K1, K2, K3: TCnDESKey); overload; +var + I: Integer; +begin + if Length(Keys) < CN_TRIPLE_DES_KEYSIZE then + while Length(Keys) < CN_TRIPLE_DES_KEYSIZE do + Keys := Keys + Chr(0); + + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Ord(Keys[I + 1]); + K2[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE]); + K3[I] := Ord(Keys[I + 1 + CN_DES_KEYSIZE * 2]); + end; +end; + +procedure Make3DESKeys(Keys: TCn3DESKey; var K1, K2, K3: TCnDESKey); overload; +var + I: Integer; +begin + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Keys[I]; + K2[I] := Keys[I + CN_DES_KEYSIZE]; + K3[I] := Keys[I + CN_DES_KEYSIZE * 2]; + end; +end; + +procedure Make3DESKeys(Keys: TBytes; var K1, K2, K3: TCnDESKey); overload; +var + I, Len: Integer; +begin + Len := Length(Keys); + if Len < CN_TRIPLE_DES_KEYSIZE then + begin + SetLength(Keys, CN_TRIPLE_DES_KEYSIZE); + for I := Len to CN_TRIPLE_DES_KEYSIZE - 1 do + Keys[I] := 0; + end; + + for I := 0 to CN_DES_KEYSIZE - 1 do + begin + K1[I] := Ord(Keys[I]); + K2[I] := Ord(Keys[I + CN_DES_KEYSIZE]); + K3[I] := Ord(Keys[I + CN_DES_KEYSIZE * 2]); + end; +end; + +function TripleDESGetOutputLengthFromInputLength(InputByteLength: Integer): Integer; +begin + Result := (((InputByteLength - 1) div CN_TRIPLE_DES_BLOCKSIZE) + 1) * CN_TRIPLE_DES_BLOCKSIZE; +end; + +procedure TripleDESEncryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Str: AnsiString; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +procedure TripleDESDecryptEcbStr(Key: AnsiString; const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; + + // ĩβ 0 ⲿжɾ +end; + +procedure TripleDESEncryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector: TCnDESIv; + Str: AnsiString; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Str := Input; + MakeInputAlign(Str); + + if Str = '' then // մֱӷؿ + begin + if Output <> nil then + Output[0] := #0; + Exit; + end; + + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Str) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Str[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure TripleDESDecryptCbcStr(Key: AnsiString; Iv: PAnsiChar; + const Input: AnsiString; Output: PAnsiChar); +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + Move(Iv^, Vector[0], SizeOf(TCnDESIv)); + + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE + 1], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Output[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; + + // ĩβ 0 ⲿжɾ +end; + +function TripleDESEncryptEcbStrToHex(const Str, Key: AnsiString): AnsiString; +var + TempResult, Temp: AnsiString; + I: Integer; +begin + SetResultLengthUsingInput(Str, TempResult); + TripleDESEncryptEcbStr(Key, Str, @TempResult[1]); + + Result := ''; + for I := 0 to Length(TempResult) - 1 do + begin + Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); + if Length(Temp) = 1 then + Temp := '0' + Temp; + Result := Result + Temp; + end; +end; + +function TripleDESDecryptEcbStrFromHex(const HexStr, Key: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + TripleDESDecryptEcbStr(Key, Str, @(Result[1])); +end; + +function TripleDESEncryptCbcStrToHex(const Str, Key, Iv: AnsiString): AnsiString; +var + TempResult, Temp: AnsiString; + I: Integer; +begin + SetResultLengthUsingInput(Str, TempResult); + TripleDESEncryptCbcStr(Key, PAnsiChar(Iv), Str, @TempResult[1]); + + Result := ''; + for I := 0 to Length(TempResult) - 1 do + begin + Temp := AnsiString(Format('%x', [Ord(TempResult[I + 1])])); + if Length(Temp) = 1 then + Temp := '0' + Temp; + Result := Result + Temp; + end; +end; + +function TripleDESDecryptCbcStrFromHex(const HexStr, Key, Iv: AnsiString): AnsiString; +var + Str: AnsiString; +begin + Str := HexToAnsiStr(HexStr); + SetResultLengthUsingInput(Str, Result); + TripleDESDecryptCbcStr(Key, PAnsiChar(Iv), Str, @(Result[1])); +end; + +function TripleDESEncryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + MakeInputBytesAlign(Input); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function TripleDESDecryptEcbBytes(Key: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + end; +end; + +function TripleDESEncryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + MakeInputBytesAlign(Input); + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + + // CBC ݿֵȸ Iv + PCardinal(@StrByte[0])^ := PCardinal(@StrByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@StrByte[4])^ := PCardinal(@StrByte[4])^ xor PCardinal(@Vector[4])^; + + // ټ + DesData(dmEncry, SubKey1, StrByte, OutByte); + DesData(dmDecry, SubKey2, OutByte, StrByte); + DesData(dmEncry, SubKey3, StrByte, OutByte); + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ܽµ Iv + Move(OutByte[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +function TripleDESDecryptCbcBytes(Key, Iv: TBytes; Input: TBytes): TBytes; +var + StrByte, OutByte: TCnDESBuffer; + K1, K2, K3: TCnDESKey; + Vector, TV: TCnDESIv; + I: Integer; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Length(Input) <= 0 then + begin + Result := nil; + Exit; + end; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + FillChar(Vector[0], SizeOf(TCnDESIv), 0); + MoveMost(Iv[0], Vector[0], Length(Iv), SizeOf(TCnDESIv)); + + SetLength(Result, (((Length(Input) - 1) div CN_DES_BLOCKSIZE) + 1) * CN_DES_BLOCKSIZE); + for I := 0 to Length(Input) div CN_DES_BLOCKSIZE - 1 do + begin + Move(Input[I * CN_DES_BLOCKSIZE], StrByte[0], SizeOf(TCnDESBuffer)); + Move(StrByte[0], TV[0], SizeOf(TCnDESIv)); // ȴһ + + // Ƚ + DesData(dmDecry, SubKey3, StrByte, OutByte); + DesData(dmEncry, SubKey2, OutByte, StrByte); + DesData(dmDecry, SubKey1, StrByte, OutByte); + + // CBC ݿֵܺٸ Iv + PCardinal(@OutByte[0])^ := PCardinal(@OutByte[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@OutByte[4])^ := PCardinal(@OutByte[4])^ xor PCardinal(@Vector[4])^; + + Move(OutByte[0], Result[I * CN_DES_BLOCKSIZE], SizeOf(TCnDESBuffer)); + + // ĸµ Iv + Move(TV[0], Vector[0], SizeOf(TCnDESIv)); + end; +end; + +procedure TripleDESEncryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then // β 0 + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure TripleDESDecryptStreamECB(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + DesData(dmDecry, SubKey3, TempIn, TempOut); + DesData(dmEncry, SubKey2, TempOut, TempIn); + DesData(dmDecry, SubKey1, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +procedure TripleDESEncryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Vector: TCnDESIv; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + + Vector := InitVector; + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError.Create(SCnErrorDESReadError); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + + Move(TempOut[0], Vector[0], SizeOf(TCnDESIv)); + Dec(Count, SizeOf(TCnDESBuffer)); + end; + + if Count > 0 then + begin + Done := Source.Read(TempIn, Count); + if Done < Count then + raise EStreamError.Create(SCnErrorDESReadError); + FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0); + + PCardinal(@TempIn[0])^ := PCardinal(@TempIn[0])^ xor PCardinal(@Vector[0])^; + PCardinal(@TempIn[4])^ := PCardinal(@TempIn[4])^ xor PCardinal(@Vector[4])^; + + DesData(dmEncry, SubKey1, TempIn, TempOut); + DesData(dmDecry, SubKey2, TempOut, TempIn); + DesData(dmEncry, SubKey3, TempIn, TempOut); + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError.Create(SCnErrorDESWriteError); + end; +end; + +procedure TripleDESDecryptStreamCBC(Source: TStream; Count: Cardinal; + const Key: TCn3DESKey; const InitVector: TCnDESIv; Dest: TStream); overload; +var + K1, K2, K3: TCnDESKey; + TempIn, TempOut: TCnDESBuffer; + Vector1, Vector2: TCnDESIv; + Done: Cardinal; + SubKey1, SubKey2, SubKey3: TSubKey; +begin + if Count = 0 then + begin + Source.Position := 0; + Count := Source.Size; + end + else + Count := Min(Count, Source.Size - Source.Position); + + if Count = 0 then + Exit; + if (Count mod SizeOf(TCnDESBuffer)) > 0 then + raise ECnDESException.Create(SCnErrorDESInvalidInBufSize); + + Vector1 := InitVector; + Make3DESKeys(Key, K1, K2, K3); + MakeKey(K1, SubKey1); + MakeKey(K2, SubKey2); + MakeKey(K3, SubKey3); + + while Count >= SizeOf(TCnDESBuffer) do + begin + Done := Source.Read(TempIn, SizeOf(TempIn)); + if Done < SizeOf(TempIn) then + raise EStreamError(SCnErrorDESReadError); + + Move(TempIn[0], Vector2[0], SizeOf(TCnDESIv)); + + DesData(dmDecry, SubKey3, TempIn, TempOut); + DesData(dmEncry, SubKey2, TempOut, TempIn); + DesData(dmDecry, SubKey1, TempIn, TempOut); + + PCardinal(@TempOut[0])^ := PCardinal(@TempOut[0])^ xor PCardinal(@Vector1[0])^; + PCardinal(@TempOut[4])^ := PCardinal(@TempOut[4])^ xor PCardinal(@Vector1[4])^; + + Done := Dest.Write(TempOut, SizeOf(TempOut)); + if Done < SizeOf(TempOut) then + raise EStreamError(SCnErrorDESWriteError); + + Vector1 := Vector2; + Dec(Count, SizeOf(TCnDESBuffer)); + end; +end; + +end. diff --git a/CnPack/Crypto/CnFloat.dcu b/CnPack/Crypto/CnFloat.dcu new file mode 100644 index 0000000000000000000000000000000000000000..609c33e673b3341b651478b135b8b56c24b5cb19 GIT binary patch literal 15913 zcmds7eSDMEy+3*KJmqN#ZG?irfTg{Jm0G%%qN@zBZ%-}WrWBeuaDWYMl157kX`Xmrk|%AQ zFT4BW-Y7li{NCTr`904`Y(|p3coiWrdTU7;?kk%b+;X|o z-{|!@o8OIf3hpUoEiKJ1r?0s4$t@ny?hm?tn0xFm9;wpV-0FH9Q@8k~7JuVzQIg!! zYG2@*Wq-Ks$8Wk*9Bkec${X^e+t+Nl#nlkVSGEVi)%0+K)iXnbUGEB1Ia`~`TN+(n zikPDz>YQ#@xwE-h+0o$I7JzZLCZS8+0hhnL#n&3}2OB85ISF0na<}+h6|OjXD@B_% z;T7K2ZO%YLlaE4Y#i1^@GuRA!e2vX6e+$LM?W}R#z8cD$K3GE$nHp22-{sOU+ktVX z)OmfLX4l?xju+fh5CxaV<$vH;tv_<7RI~)QG`o6)%`doRWkWaPhg#xdYbC+OhqVXDXAxkxPF6`X4-UX=|(3<8w7~ zQk^oHkpl4ei}yX^NrC4sKNrr0aKMEHmufx6)xHMCpI!nVwg*)gO8@DzcO3F?Ii;VRjTU+`F1r3ZzMzFK3KODJ7=vw!2G-&>`T zs;l%8p3h2J(#<;u>bL#eEz@|HH#zTTuxmtND%YIdI zt;bZd&gpG+@gnE8Rk!#&bW73g2VZV(ZVt9K`BilNp42L>65swo z=+TD848F_rF*pL==2p1mo@VD3Rk@nCA$8t&mbf$Qn#~;eJ=u5MJ=IQ);DE6=j+eMi zcDAKCWXI;aO5CaOz1h4krN%QizRagip@8Fn{f~a;bGQZ0 zzrV$QrvA1Pk11aV`Oz}_*Bcts)x4B9J6l^_G%ZQFV#gYQo~d;SSzfQZ1e{+&8E^CE zV`yx-opZ|Nz8Yu1dmG)??kQ?|>B-x0wbmN;5OVX;yMHY-T%9=h#j9nQ!E|+i6Q9Q@ z12?II0m!2bjEEJF3i?U|sKBV!+-@BOc)pSlftAXx`9tL=3_lEGxHqW+XyYhV&td4% zdv>HD*JLmEtqnRG{lRTGUkMrd^{i)>=bCDhq5t$$_6sX=(?GkXA)rzQ+j^c|m7502 z1nilEwT&f zlX7$MK0;2ky-`?6h}k-00=lpO_+N5-=4AM5fIr9a7KX1|eSHl?*IZw%+-xhY`$yo< zcKNqd5t4y;btGsi);P)%G^d~4&~}4t1_}LiSZBf%CMs^ODs0KyvBGLXj6}4~(rDH? zN-NemY7^3uG+xQPs$El~)Y!*a_IbajpoUr2(QZwmOSbO54>q*bYSs<4Tj%ISj<+z^ zKU}zukPl);>s&qE1S`i8Qg>HZt}ZXFp}ElqFwgJ#0nEG!NgI&3erBJ7+#7PHPDM?Zhm2y;`Zc-d=^w z|Cv`tKBHAF{V>|9-K+|mtXV8*@ghwGMK9UQsdp!*VohabouVZf`WLq|nU@Wdl5vAT zmOJ(~&DiA(>t~p5wN_MVTFfZnk#~4%4Qlc6EUl)yiZg-eKaaj%XeUG(OQI=Vuct{E zMvGX>VX~Y8_vZ_5gq$HJN25uWldycYK5Djcl8)q4NmI#~HJNOju()?$5b~GeL|9L( zS2|YL*socZI5prX_VxNSLJ%>dAQW9$M>Vfow`N^}h#oE2#TOi8m->De})g)_%AZC&*qkFXv&$H8KXQipc%8qRSh_7c|QQCaF6OTCb z$zfZI&*ckH_^+~4D_i_90xGfI-2D$Jc=p2cJru!u^93}zU62`&YTHOXdZMBV#;6eGV#ToSOh1`Z!wky-GDT`(6IlCLrj{)lrmAz8<{9W-4?`j zBrCPr<;JsBMGNH>-_;9-Ko;in7DF>t(5EWswHUV2^(hNi+^s3R<=ar$Llxe7;Gi%* z!tiB$giB{qTMmq|N?G(b1Q`z$d=FGO15VhsIck}j45@#>A_lf@s{=9<4zY;o9Ab{b zA?8^3_^OF#4s}^cNHelD$2i}p&zujiEDBRI2g*;MxoxKrNGp?u%xR(?|NCXmzXu9e zQiZo3m~R}PIT$cLbI#2FBbm#=yGX$AMBeCq3x6BH25%ZXdV(Afa1v)pH#(bxF4Tp| zoNcPZD>P0S_H6zfo^i#IY`pjL6N;|Whq7gx(--izwmRurh&Ci^;4c@@@a%JM?;@!} zvI_I3P*DsOnR+L5x#)af$|v_G>zMv2bqr@ z!&My3jzg-vHVQE#faNV)w|IT7ldoZq&;X(8YJ8x>5)DO^Dn^)}?p z)GN|w=*ZsJ?Ww8U4yf{ub8kA_OL4Hg5PY@?;&hT_a4;%MqBl=J z->^TmR4j<)r1P5!ysWbuHB^u1xoh7d*9f9%GDgz~7;WNG9b-H}d+yru7Fi*P=E)e% zLtxw>E{o-uHI2H+zn$^+FlGI4V_nqP6bCLx`Gwa(oUO%BR0-Fnn{}=g4_OR$H)AMji$oBMXO)(L90i zKFWy85q?XlV`br}P3RowAap*=Sh=yQaZlj(;(E#jb8kPMnoG6_qDZn*N)rdAEob_YceSxx0OW4hsnaR68(&V=&vx!}DdhbBTX`wdLOGA<_WZe@W4F`lA z?KTJ)_Av`tGR2J9zHhMf0`vf}UPnltP~AcVQcU)zUKXj37lspCCRB4eRH36p7Df9NHP6K$F3T`-PAt{0&Jcv=o z8_t6dDh2WxvYgmlhLW>7+bXG08Ma*^KuUQ zB)~-!T(CcNKEU%;aD$R3zd%-z>mi<03{`HCUm_$sluHWw#4%iwTt^xzz=n6Z%ZAIw z3QASQ-o)7VFrCI52_CL*AY%rhf{2t1ul5%>-FlLNi-GnYPE*UjxWVO&c3aTi5oa;} z87x$bVeGQuQ4TheQQUz%!c?wjmp@G01GYj#=GCCp5*I%=Ab_SXOUgE6G4F1QQC7(-1yWCJ_ZeoFLa-3x6(MVnF<=%Uc(IgcSj?E~ zxnTP01YEkjKXr+eZ&;$?Qnlxu)f5Z0g}@f7*an5hFhHvDwo1rtbJ-~DNUtV%k0f_s zor7@~Mg*4Z#yA@$bpW4<^;fW7fpO2=68uHRpaDT&KvTnJDcVd(i_dbj8A*@NL~SNy z#%C)o8=DvVkwuc8bn8eBVIN7GU=*-nXcn+d=!)(WzBH-JLfsO(g0IpkQuq>ZbWK%d zCS7F$01PuhcbRFSVEUm5?IQ@4s!(PCHUn2dtp#o=UmyAh?b1jH}-qiLyE z!Dv@xUNXriUI}F4y(-l+Wg<9Xj&^oYZQLCmg7k4W8?E`(*YU<)<(;B#M^hD~HO2}W!-~9y3v@yi2)=GP4?K%Mm{T7I{tJKHOJdjUG`p7=i2G765Y(r^DVP{A2`j@LZSNQYU+&s; zG4h$UCyn%K>j{bpwT%ct)5&tf5(=SAKf^!bJ_fya_6E{VigOAnkkSsCLSrN#15|)j zsrxr?xY^hN6Q1s*F8rU`tiTp3N8r=q8US=ZnsS%?R+ZMg)L`cfdyxj%et( z0QeL1q-Su@hKfnxa~LD={ai#jx6cvV3+8hX$4IzVWRu}=tvrwi38A)O63l^w2p3zG zarb5T8*#`iAV&jneXj%D(e?((*z;}JjF6JRW<<~sT+-#}jVQxhyQ8;DIm^rPjxA$^~9$s@x2;x!m7}Suxt86n<#TJS$&}HlyW!%Fhp^+UKU!6hQr81nL2`f=7ik^u$RF{=# z3FcSzX595O7|X(rK2DOzRZNM-Y<QWeg7~z= zkdMHXgrde>mXfg2cT$Pc4L~CnFA7aj#3n~lsmW?|2J>_!^pFFmMLu1(7v<8qa<&c)}ajwt5ZSkM#;%Gi9hUAEzUj^ z38-i$HX6pJQbtcI!xR*18zq6OBg&{14@@09rK-@Wp^|+az+guW@2!~mCM%`UJG*xp zL){rYBO-VyQ}EfC4K+5BD65mo5SKVic4q^_4RZ{ki1$@bdvk9!zV%Utz(sd(`|n}$ z)6AgLVcYOt#|MxLGZ<4?x!BS60SRE2U$i1-+^*4*W7L_edOKg`up2_Z97XX)2PGPy zsH*>@(ofBxpz{%B=!?q5b~^+|977pDt}w?!(E^-7m-4V7{nI@H!rc7HZ;QuIe`{qXx)=C`e%qT4U1 zPOp7p8noYn|5gXzTl+7z(K=nO9Zf%lpS(kLDZP`X{)pkQLDf2p^DP$)h`4qlviOYw zK82l^XAQxH5v7l((AYB~u-)FLk8D`!A6yQassvHVC4MR-(M_HK1mfZsmHxJkh(#Hz z37&i9VyGLZSAW@6y}Le(Or2vX(F)`IFOZIc7*b$67mPZ(Y^RwEN4R4fA`ZG{f(HH> z(c(IS3qW{k93fpZ!om73WvCW`FJ%hy_nH^&yA=cQe+a zGa7=fkI{|G0H_tj^+CjyojKP587pXtg0;(WG@?YgHpkH}<;g^why|Z)qR# z9Ken)<&jzjWexclgsTx#9_g|@riCG5dkjR!@}Q9^8hC(-Jd4hiju|Qkd#BCCqu)0% z`V5p5{fCmG|Bx2_2be9I+E|dT6VV@799I_1Laz2R>O{rRHMfs&LR~qd=#jhy8DAY7 zrTwuFq;&K0z@fNUsrDr*HLA(NaiLZ!dLpmXZ;#VU*Ie&j#1F!ZNm~h`AB$C>t+=IhRWxc1%cCQw#i0xk3acqT_q>i>; z))m1+;nf;E-W8A2vQ_RmM&AaQye{RaIzD*})Eba0i}%ITtS_<$cdfBetM!eL?w8FK zIZ2IeF<=@!!z&3q-4&aa9NPQhG_({8Ayng`>jK@H>ZA->*P}8h4TZDD(*Gfy4i_@K zql_eVy4UobZc5LH@l$rX*FLnL3ulF;0pwK#H`52(De=H4nYNz~Xnd;|xF3M!5uzQ*6B?K` zuIwWk7=NXUS25n7)b=&)^53z2sSjGTeQCQx-@Lx|cW+*z)}+QYuS^XdZ(avzjs9Jl z7gB_4(nRB-Yel!FO-4cI(Kn`#)2Ot!x?$dzx)k}{5@QG6O)|a#PjH`M#V%~`iQ-bF zo!)#19Ef`o`Ysm6t;ukw3=%@$_Qd#0VnSR5cO`i7>3kIicF@ZnV`zkAe4{(!7~RW+ zCGbP-k>fql%%U?(V%WxUZIqz%Rr*UlytRc5;k6=^GO?Y%#22CoC@hdCvEbd3)PzIs zNQvyW#@aJ}(v9mbRSV>GIpj!MSdQEvhO0#W=E_1d#4hfJ&?I?)=w;o{;fmTR97F6H zj&0wFZRm*MAaHy)Ggy~m%J@l1`XTDP7E}{#NT1vWQ^E#t!qlQO>uR|SQ_-17Z&CMD zap6?^LNRngrp_DSyv#xpFTvALr9G>~pN{^h-Wuq$jd%D?*Dw+pgZoyVP&q7wl#zBE z7d_{%#1&7fz)s+)xCEhDCLM$HKBUuv-QGSi;gHB~OH4Fde~N__IqWbcAc_2S;y|Vu zRz~iN^!B`(S=5cpPBlzLX4MQcwX^kkM*LJ9y>Lh zw{}!9l8$SO5t;y0usd8PYd#LUJF8^wBc}B-_fajWq(Wf#AC4v(>yKFoi7<@C0|U#< z)Ur%=pNMNFnqzFLGC87Pik#5;#M(5e-RaD31bDc!iaz*u45ra}y@>`TUJt+h$a=to z3Du3myz@;eChWNQhpo|b61`MFK->9xu*H&pY!FYqqY3nhgJEDn?}F$qB6Q6 zzW+va$X7OveCHKqWJ3Zwq{AjDVCC6IFE#L*e~xao=b@2DSa;RbWjo*HxY(tSa}rHK(10Q;zEPo0JT9*pI%Pi1Ud9Z z*nxW#er*|6M#7HKc(BhwT9?w7cw>$4zyaEV9izIFW#mOg4xJc&dBwu-Fh95`PDX>J z9;PF&{B<(5JV$i#nN*yKo{Vb~NBT-+x;;1*fJ?YWY$pM+sC!U2Y(Qz_0#DP=81yG} z=ll5aetU2}4)Ne@DlKt3Ylr&;Nz6nlNjrSm_Yvs;gm#FuA>gKcy!MYWH#nYwh3k`= zn@ZgnFKKdflbnsUQ)egTHjx+}3kZ2S#9kZ?Pj59~-AlyYRbu8mQC>j*H_sEz3&|NG zo>?gNn#frqo?R|ZpQru5ki0;|7cAmg6X_#jpGADhEcUVgzbT8eWO24E-Ybi9WpSP? zE|5iwEN08%LRnlSi}%Rl-Lm-gV)7CZU&yn&$N|JeR${(VSSprcjxUcfR*PvlV(ua_cPUvb+#s$Ma;4%0Qt=WA(==&afmF6z zs>)%D>S}4fMY?eoTiEC77nxGkLQXSFT3;+x%{zf?d2{sF#X! zrP>P8BP^1t&WH~S%K_Xh70;7uSCNB4g?Lb?0b7n#l_f~U%b{KB5oSy4mh)k$bW65W zHV=#GptNAjmYSDgI*U1J#%!+CoQq+$bcoSlxd6*~iDj--RU+LomkIs8x?$oEq<3Q7MF^P#qs3t1E!Ieip#}P@fu zF|&#^@t7 +================================================================================ +* ƣ +* Ԫƣת +* ԪߣǬԪ(wqyfavor@163.com) +* עõԪʵ Extended תΪˡʮַĺ +* 㷨Ƕȡ Extended ڴеĶݽת Extended ͵˵ +* ԲοϡDouble Single Ϊϵͳֵ֧ͨĸͣ Delphi е +* Extended ڴ洢ʽвͬ߾β񻯣 Double Single β +* Ĭϵ 1βΪ 1.001 Double Single д洢Ϊ 001ȥ +* Сǰ 1 Extended 洢Ϊ 1001 +* NaN Ϊ "not a number"Ǹο Math.pas Ԫеij NaN +* Infinity Ϊ󣬶ο Math.pas Ԫеij Infinity NegInfinity. +* һ DecimalExp AlwaysUseExponent +* ʮƸתʱָʽѧ㷨Щ +* Ҳָֻʽ 1E-1000ָʱ 0.0000000...0001תָ +* ҲӦӦƱʾʱʮƱʾָ֣ƴ +* 1.001E101ֵΪ 100100ָʮƱһЩ 1.001D5ʾС +* 5 λDecimalExp ָǷʮƱֵָġע⣬ʮ +* ʾָ޹涨﷨ʹ "D" ʾ"E" ΪӦƱʾ⣬ +* ʮƱȽ⣬"D" "E" ΪʮַʮƱʱʹ "^" +* ַ 3.BD^D(12)A.BD^E(ABCE)粻ϲָʽ޸ġ +* AlwaysUseExponent ָǷһÿѧ 100.111 λȽ٣ +* ԶжϲҪʹÿѧ AlwaysUseExponent ΪʱһΪָ +* ʽ 1.00111E2 +* const +* MaxBinDigits = 120; +* MaxHexDigits = 30; +* MaxOctDigits = 40; +* ָλʱһʹÿѧ +* +* ⣬Extended ֻ Win32 10 ֽڣMacOS/Linux x64 ¾ 16 ֽڣWin64 ARM ƽ̨ 8 ֽ +* ңMacOS64 µ 16 ֽչȲ IEEE 754-2008 й涨 Quadruple ʽǰ 10 ֽڽضϣ +* ڲṹͬ Win32 µչ 10 ֽ +* +* ƽ̨WinXP + Delphi 2009 +* ݲԣDelphi 2007 Extended ֻ֧Сģʽ +* õԪеַϱػʽ +* ޸ļ¼2023.01.13 +* ݴ Win64 Extended 8 ֽ Double 10 ֽչȵ +* ݴ MacOS64/Linux64 µ 16 ֽ Extendedֻضϴǰ 10 ֽڣ +* 2022.02.17 +* FPC ı֧֣ +* 2021.09.05 +* תΪ UInt64֧ UInt64 Int64 棩ĺ +* 2020.11.11 +* UInt64֧ UInt64 Int64 棩תΪĺ +* 2020.06.24 +* ⿪ƴյĺ +* 2009.1.12 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, SysConst, {$IFDEF MSWINDOWS} Windows, {$ENDIF} CnNative; + +{ + IEEE 754 涨ָʽЧڵλ 0 + + Single 1 λ S8 λָ E23 λЧ M 4 ֽ 32 λ + ˫ Double 1 λ S11 λָ E52 λЧ M 8 ֽ 64 λ + չ˫ Extended 1 λ S15 λָ E64 λЧ M 10 ֽ 80 λ + + IEEE 754-2008 + ı Quadruple 1 λ S15 λָ E112 λЧ M 16 ֽ 128 λ + ˱ Octuple 1 λ S19 λָ E236 λЧ M 32 ֽ 256 λ + + Уλ S0 ʾ1 ʾE Ҫȥ 127/1023/16383/16383 ָ + M: 淶/˫ȵĶ M ĸλӸ 1. Чչӣ 1. + ֵЧ 1.xxxx ʽ 2 E ηעⲻ 10 E η + + ʽ ֽ 1 ֽ 2 ֽ 3 ֽ 4 ... ֽ nÿֽڵұߵλ 0 + 4 SXXXXXXX XMMMMMMM MMMMMMMM MMMMMMMM + ˫ 8 SXXXXXXX XXXXMMMM MMMMMMMM MMMMMMMM ... MMMMMMMM + չ˫ 10 SXXXXXXX XXXXXXXX 1MMMMMMM MMMMMMMM ... MMMMMMMM // עЧְ 1඼ʡ 1 + ı 16 SXXXXXXX XXXXXXXX MMMMMMMM MMMMMMMM ... MMMMMMMM + ˱ 32 SXXXXXXX XXXXXXXX XXXXMMMM MMMMMMMM ... MMMMMMMM + + ע⣺Little Endian ϣֽ 1 n 򡣱Ԫѵ + + 0ȫ 0 + -0ȫ 0 λΪ 1 + ָȫ 1Чȫ 0 0 1 +} + +type + TCnQuadruple = packed record + {* Delphi ıͣýṹָ} + Lo: TUInt64; + Hi0: Cardinal; + case Boolean of + True: (Hi1: Cardinal); + False: (W0, W1: Word); // С˻ϣźָ W1 + end; + PCnQuadruple = ^TCnQuadruple; + + TCnOctuple = packed record + {* Delphi ް˱ͣ Int64 ָ} + F0: Int64; + F1: Int64; + F2: Int64; + F3: Int64; + end; + PCnOctuple = ^TCnOctuple; + + ECnFloatSizeError = class(Exception); + +const + CN_EXTENDED_SIZE_8 = 8; // Win64 µ Extended ֻ 8 ֽ + CN_EXTENDED_SIZE_10 = 10; // Win32 µ Extended DZ׼ 10 ֽ + CN_EXTENDED_SIZE_16 = 16; // MACOS64/Linux64 16 ֽ + + CN_SIGN_SINGLE_MASK = $80000000; + CN_SIGN_DOUBLE_MASK = $8000000000000000; + CN_SIGN_EXTENDED_MASK = $8000; // ȥ 8 ֽЧ + CN_SIGN_QUADRUPLE_MASK = $80000000; // ֻǰֽڣȥ˺ + + CN_EXPONENT_SINGLE_MASK = $7F800000; // Ҫ 23 λ + CN_EXPONENT_DOUBLE_MASK = $7FF0000000000000; // Ҫ 52 λ + CN_EXPONENT_EXTENDED_MASK = $7FFF; // ȥ 8 ֽЧ + CN_EXPONENT_QUADRUPLE_MASK = $7FFF; // ȥ 14 ֽЧ + + CN_SIGNIFICAND_SINGLE_MASK = $007FFFFF; // 23 λ + CN_SIGNIFICAND_DOUBLE_MASK = $000FFFFFFFFFFFFF; // 52 λ + CN_SIGNIFICAND_EXTENDED_MASK = $FFFFFFFFFFFFFFFF; // 64 λʵȫ 8 ֽ + CN_SIGNIFICAND_QUADRUPLE_MASK = $FFFF; + + CN_SINGLE_SIGNIFICAND_BITLENGTH = 23; + CN_DOUBLE_SIGNIFICAND_BITLENGTH = 52; + CN_EXTENDED_SIGNIFICAND_BITLENGTH = 63; + + CN_EXPONENT_OFFSET_SINGLE = 127; // ʵֵָҪܴ浽ڴָ + CN_EXPONENT_OFFSET_DOUBLE = 1023; + CN_EXPONENT_OFFSET_EXTENDED = 16383; // 10 16 ֽչȸΪ + + CN_SINGLE_MIN_EXPONENT = -127; + CN_SINGLE_MAX_EXPONENT = 127; // Max ָȫ 1 Σ + CN_DOUBLE_MIN_EXPONENT = -1023; + CN_DOUBLE_MAX_EXPONENT = 1023; + CN_EXTENDED_MIN_EXPONENT = -16383; + CN_EXTENDED_MAX_EXPONENT = 16383; + +procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: Cardinal); +{* ӵȸнλָЧ֡ + עָΪʵָЧΪ 24 λԭʼΪ 0~22 λ 23 λΪȥ 1 + + + Value: Single - ⿪ĵȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: Cardinal - Ч + + ֵޣ +} + +procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +{* ˫ȸнλָЧ֡ + עָΪʵָЧΪ 53 λԭʼΪ 0~51 λ 52 λΪȥ 1 + + + Value: Double - ⿪˫ȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: TUInt64 - Ч + + ֵޣ +} + +procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +{* չȸнλָЧ֣֧ 10 ֽڡ + Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ + עָΪʵָЧΪȫ 64 λλ 63 λΪԴ 1 + + + Value: Extended - ⿪չȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out Mantissa: TUInt64 - Ч + + ֵޣ +} + +procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out MantissaLo: TUInt64; out MantissaHi: TUInt64); +{* ʮֽھȸнλָЧֻ֣ Extended Ϊ 16 ֽ + Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ + עָΪʵָЧ 112 λΪߵ֡ + + + Value: Extended - ⿪ʮֽھȸ + out SignNegative: Boolean - λTrue Ϊ + out Exponent: Integer - ָ + out MantissaLo: TUInt64 - Чֵ 64 λ + out MantissaHi: TUInt64 - Чָ 64 λ + + ֵޣ +} + +procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; + Mantissa: Cardinal; var Value: Single); +{* ѷλָЧƴɵȸ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: Cardinal - Ч + var Value: Single - ϵĵȸ + + ֵޣ +} + +procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Double); +{* ѷλָЧƴ˫ȸ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: TUInt64 - Ч + var Value: Double - ϵ˫ȸ + + ֵޣ +} + +procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Extended); +{* ѷλָЧƴչȸ֧ 10 ֽڡ + Լ 16 ֽڽضΪ 10 ֽڵ Extended ʽ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + Mantissa: TUInt64 - Ч + var Value: Extended - ϵչȸ + + ֵޣ + +} + +procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; + MantissaLo: TUInt64; MantissaHi: TUInt64; var Value: Extended); +{* ѷλָЧƴչȸֻ Extended Ϊ 16 ֽ + Ҹʽ IEEE 754-2008 ıȸʱЧĿǰ Delphi ָ֧øʽ + + + SignNegative: Boolean - λTrue Ϊ + Exponent: Integer - ָ + MantissaLo: TUInt64 - Чֵ 64 λ + MantissaHi: TUInt64 - Чָ 64 λ + var Value: Extended - ϵʮֽھȸ + + ֵޣ +} + +function UInt64ToSingle(U: TUInt64): Single; +{* Int64 зģ 64 λ޷͸ֵ Singleʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵSingle - صĵȸ +} + +function UInt64ToDouble(U: TUInt64): Double; +{* Int64 зģ 64 λ޷͸ֵ Doubleʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵDouble - ص˫ȸ +} + +function UInt64ToExtended(U: TUInt64): Extended; +{* Int64 зģ 64 λ޷͸ֵ Extendedʵͬ + + + U: TUInt64 - ֵ 64 λ޷ֵ + + ֵExtended - صչȸ +} + +function SingleToUInt64(F: Single): TUInt64; +{* Single ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Single - ֵĵȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function DoubleToUInt64(F: Double): TUInt64; +{* Double ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Double - ֵ˫ȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function ExtendedToUInt64(F: Extended): TUInt64; +{* Extended ֵ Int64 зģ 64 λ޷ͣʵͬ + + + F: Extended - ֵ˫ȸ + + ֵTUInt64 - ص 64 λ޷ֵ +} + +function SingleIsInfinite(AValue: Single): Boolean; +{* ȸǷ + + + AValue: Single - жϵĵȸ + + ֵBoolean - Ƿ +} + +function DoubleIsInfinite(AValue: Double): Boolean; +{* ˫ȸǷ + + + AValue: Double - жϵ˫ȸ + + ֵBoolean - Ƿ +} + +function ExtendedIsInfinite(AValue: Extended): Boolean; +{* չȸǷ + + + AValue: Extended - жϵչȸ + + ֵBoolean - Ƿ +} + +function SingleIsNan(AValue: Single): Boolean; +{* ȸǷʵ + + + AValue: Single - жϵĵȸ + + ֵBoolean - Ƿʵ +} + +function DoubleIsNan(AValue: Double): Boolean; +{* ˫ȸǷʵ + + + AValue: Double - жϵ˫ȸ + + ֵBoolean - Ƿʵ +} + +function ExtendedIsNan(AValue: Extended): Boolean; +{* չȸǷʵ + + + AValue: Extended - жϵչȸ + + ֵBoolean - Ƿʵ +} + +// FPCWindows 64/Linux 64 ƽ̨Լ Delphi 56 ֧ +{$IFDEF WIN32} +{$IFDEF COMPILER7_UP} + +{ FloatDecimalToBinExtended, FloatDecimalToOctExtendedFloatDecimalToHexExtended + FloatDecimalToBinaryExtended ̣FloatDecimalToBinaryExtended } + +function FloatDecimalToBinExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to binary + +function FloatDecimalToOctExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to octal + +function FloatDecimalToHexExtended(fIn: Extended; DecimalExp: Boolean; + AlwaysUseExponent: Boolean): AnsiString; // Convert to hexdecimal + +{$ENDIF} +{$ENDIF} + +implementation + +const + UINT64_EXTENDED_EXP_MAX = $4040; // UINT64 Ӧ Extended ָ + +resourcestring + SCN_ERROR_EXTENDED_SIZE = 'Extended Size Error'; + +type + TExtendedRec10 = packed record + {* 10 ֽڵչȸֻ Win32 Ч} + Mantissa: TUInt64; + ExpSign: Word; + end; + PExtendedRec10 = ^TExtendedRec10; + +{$IFDEF WIN32} +{$IFDEF COMPILER7_UP} + +type + PConvertFloatSystem = ^TConvertFloatSystem; + TConvertFloatSystem = record + Negative: Boolean; + ExpFlag, ExponentI: Integer; + end; + +const + MaxBinDigits = 120; + MaxHexDigits = 30; + MaxOctDigits = 40; + +function FloatDecimalToBinaryExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean; var ForHexOct: PConvertFloatSystem): AnsiString; +var + Neg: Boolean; + i, Flag, IntExp: Integer; + Exp: AnsiString; +label UseExponent; +begin +{ +Extended(32.125) in memory: +0 100000000000100 10000000 10000000 00000000 00000000 00000000 00000000 00000000 00000000 + 9 8 7 6 5 4 3 2nd Byte 1stByte 0 +sign exponent digits +0 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 + Inf +1 111111111111111 1000000000000000000000000000000000000000000000000000000000000000 - Inf +1 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 Nan +0 111111111111111 1100000000000000000000000000000000000000000000000000000000000000 -Nan +} + SetLength(Result, 255); + SetLength(Exp, 2 * SizeOf(Extended) + 1); + Neg := False; + asm + push EBX + push ESI + mov EBX, Result // Address of Result + mov EBX, [EBX] + mov EAX, 0 + // Test if fIN equals 0 + lea ESI, fIn[7] // get the first byte of digits + mov AL, [ESI] + test AL, 128 // 10000000B + jz @Zero + mov ECX, 0 + lea ESI, fIn[8] + mov AX, [ESI] // Get first two bytes + test AX, 32768 // 32768D = 1000000000000000B + jz @Positive + mov Neg, 1 + sub AX, 32768 // Sign bit <- 0 + @Positive: + // Test if fIn is NaN or Infinity + cmp AX, 32767 + jnz @NotNAN_INF + mov DL, [ESI - 1] + test DL, 64 // 01000000B + jz @INF + mov Flag, 4 // NaN + jmp @Done + @INF: + mov Flag, 3 // INF + jmp @Done + @NotNAN_INF: + sub AX, 16383 // AX = AX - 011111111111111B + jns @ExpPositive + sub AX, 1 + not AX + mov Flag, 2 // // Exponent sign negative + jmp @JudgeDecimalExp + @ExpPositive: + mov Flag, 1 // Exponent sign positive + @JudgeDecimalExp: + mov IntExp, EAX + cmp DecimalExp, 1 + je @MoveDigits + // Binary string exponent. Convert AX to binary string and store it in Exp + lea EBX, Exp + mov EBX, [EBX] + push ECX + mov [EBX], 69 // 'E' // "D" for decimal exponent + mov ECX, 1 + cmp Flag, 2 + jnz @NoNegativeInExp + mov [EBX + 1], 45 // '-' // Add a "-" to exponent string + mov ECX, 2 + @NoNegativeInExp: + mov ESI, 0 // flag whehter "1" appears + // Move exponent digits to Exp + mov DX, 32768 // 1000000000000000 + @NextExpDigit: + test AX, DX + jz @AppendExp0 + mov [EBX + ECX], 49 // '1' + mov ESI, 1 + jmp @NextExpIncECX + @AppendExp0: + cmp ESI, 0 + jz @NextExpNoIncECX // do not append this "0" + mov [EBX + ECX], 48 // '0' + @NextExpIncECX: + inc ECX + @NextExpNoIncECX: + shr DX, 1 + cmp DX, 0 + jne @NextExpDigit + pop ECX + mov EBX, Result + mov EBX, [EBX] + jmp @MoveDigits + @MoveDigits: + // Move digits to Result + mov ESI, 8 + @NextByte: + dec ESI + mov EAX, EBX + lea EBX, fIn[ESI] + mov DL, [EBX] + mov EBX, EAX + mov AL, 128 // 10000000 + @NextDigit: + test DL, AL + jz @Append0 + mov [EBX + ECX], 49 // '1' + mov i, ECX + jmp @Next + @Append0: + mov [EBX + ECX], 48 // '0' + @Next: + inc ECX + shr AL, 1 + cmp AL, 0 + jne @NextDigit + cmp ESI, 0 // if the last byte + jne @NextByte + jmp @Done + @Zero: + mov Flag, 0 + @Done: + pop ESI + pop EBX + end; + case Flag of + 0: + begin + ForHexOct := nil; + Result := '0'; + Exit; + end; + 1, 2: + begin + // Delete redundant "0" in Result + Delete(Result, i + 2, MaxInt); // i stores the position of the last 1 in Result + if Assigned(ForHexOct) then + begin + // Copy to ForHexOct + with ForHexOct^ do + begin + Negative := Neg; + ExpFlag := Flag; + ExponentI := IntExp; + end; + Exit; + end; + // Add dot and exponent to Result + if (IntExp = 0) then + begin + if (Length(Result) > 1) then + Insert('.', Result, 2); + end + else + begin + { Decide whether use exponent. For example "1000.101" shouldn't be output + as 1.000101E11 when AlwaysUseExponent is False. } + if AlwaysUseExponent then + begin +UseExponent: + if DecimalExp then + if Flag = 1 then + Exp := 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)) + else + Exp := 'D-' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(IntExp)); + if Length(Result) >=2 then + Insert('.', Result, 2); + Result := Result + Exp; + end + else + begin + // IntExp may be negative. + if Flag = 1 then + begin + // Calculate all digits required without exponent + if IntExp <= Length(Result) - 2 then + begin + // Do not use exponent + Insert('.', Result, IntExp + 2); + end + else if IntExp = Length(Result) - 1 then + { 1.001, Exp = 3, output 1001 } + else + begin + if IntExp + 1> MaxBinDigits then + goto UseExponent + else + begin + Inc(IntExp); + i := Length(Result); + // Add zeros at tail + SetLength(Result, IntExp); + for i := i + 1 to IntExp do + Result := '0'; + end; + end; + end + else + begin + if IntExp + Length(Result) > MaxBinDigits then + goto UseExponent + else + begin + // Add leading zeros and place "." + SetLength(Exp, 1 + IntExp); + Exp[1] := '0'; + Exp[2] := '.'; + for i := 3 to IntExp + 1 do + Exp := '0'; //} + Result := Exp + Result; + end; + end; + end; + end; + end; + 3: // INF + begin + ForHexOct := nil; + Result := 'INF'; + end; + 4: // NaN + begin + ForHexOct := nil; + Result := 'NaN'; + Exit; + end; + end; + if Neg then + Result := '-' + Result; +end; + +function FloatDecimalToBinExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +var + PTmp: PConvertFloatSystem; +begin + PTmp := nil; + Result := FloatDecimalToBinaryExtended(fIn, DecimalExp, AlwaysUseExponent, PTmp); +end; + +function FloatDecimalToHexExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +const + DecToHex: array[0..15] of AnsiChar = + ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + BinPow: array[0..3] of Integer = (8, 4, 2, 1); + + function IntToHex(Int: Integer): AnsiString; + var + k ,t: Integer; + Buf: array[1..5] of AnsiChar; + begin + k := 1; + while (Int <> 0) do + begin + Buf[k] := DecToHex[Int mod 16]; + Inc(k); + Int := Int div 16; + end; + Dec(k); + SetLength(Result, k); + t := 1; + while (k > 0) do + begin + Result[t] := Buf[k]; + Inc(t); + Dec(k); + end; + end; + + function ToHex(const S: AnsiString; LeftToDot: Boolean): AnsiString; + var + i, l, t, m, k: Integer; + Buf: array[1..20] of AnsiChar; + begin + { LeftToDot = True, S will be patched with zeroes on its left side. + For example, S = '110', after patching, S = '0110'. + LeftToDot = False, S will be patched with zeroes on its right side. + S = '110', after patching, S = '1100'. } + l := Length(S); + if LeftToDot then + t := (4 - (l mod 4)) mod 4 + else + t := 0; + i := 1; + m := 1; + k := 0; + while i <= l do + begin + k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); + Inc(t); + if (t = 4) or (i = l) then + begin + Buf[m] := DecToHex[k]; + Inc(m); + k := 0; + t := 0; + end; + Inc(i); + end; + Dec(m); + SetLength(Result, m); + + while (m > 0) do + begin + Result[m] := Buf[m]; + Dec(m); + end; + end; + +var + PConvertData: PConvertFloatSystem; + ConvertData: TConvertFloatSystem; + tmpS: AnsiString; + k, t, i, m: Integer; +label UseExponent; +begin + PConvertData := @ConvertData; + Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); + // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. + if PConvertData = nil then + Exit; + with ConvertData do + begin + { 3.BD^D(12) + A.BD^E(ABCE) + AB.FFFF } + k := Length(Result) - 1; + if AlwaysUseExponent then + begin +UseExponent: + { Algorithm: + X.XXXXXXXX^Y Shift Count Exp + 1.00000001^0 = 1.00000001 = 1.01^0 (16) + 1.00000001^1 = 10.0000001 = 2.02^0 (16) + 1.00000001^2 = 100.000001 = 4.04^0 (16) + 1.00000001^3 = 1000.00001 = 8.08^0 (16) + 1.00000001^4 = 1.00000001^100 = 1.01^1 (16) + 1.00000001^5 = 10.0000001^100 = 2.02^1 (16) + Shift Count = Y mod 4 + Exp = Y div 4 + X.XXXXXXXXX^Y Y < 0 Exp + 1.00000001^-1 = 0.100000001 = 1000.00001^-100 = 8.08^-1 + 1.00000001^-2 = 0.0100000001 = 100.000001^-100 = 4.04^-1 + 1.00000001^-3 = 0.00100000001 = 10.0000001^-100 = 2.02^-1 + 1.00000001^-4 = 0.000100000001 = 1.00000001^-100 = 1.01^-1 + 1.00000001^-5 = 0.0000100000001 = 1000.00001^-100 = 8.08^-2 + Shift Count = 4 - (Abs(Y) mod 4) + Exp = -(Abs(Y) div 4 + 1) } + if ExpFlag = 1 then + begin + t := ExponentI div 4; // Exp + i := ExponentI mod 4; // Shift Count + end + else + begin + t := -((ExponentI - 1) div 4 + 1); // Exp + i := (4 - (ExponentI mod 4)) mod 4; // Shift Count + end; + // Get hex digits + if k < i then + begin + // Add extra zeroes + SetLength(Result, i + 1); + for m := k + 2 to i + 1 do + Result[m] := '0'; + Result := ToHex(Result, True); + end + else if k = i then + Result := ToHex(Result, True) + else + begin + tmpS := Copy(Result, 1, i + 1); + Delete(Result, 1, i + 1); + Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); + end; + if t <> 0 then + begin + // Format exponent + if DecimalExp then + Result := Result + '^D(' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + ')' + else + begin + if ExpFlag = 1 then + Result := Result + '^E(' + IntToHex(t) + ')' + else // t < 0 + Result := Result + '^E(-' + IntToHex(-t) + ')'; + end; + end; + end + else + begin + { Always remember that Result equals "XXXXXXXX" not "X.XXXXXXX". + Judge whether to use exponent: + There are K "X" after '.', K = Length(Result) - 1, no "." in Result originally. + X.XXXXXXX^Y (Binary string, ExponentI = Abs(Y)) + case Y >= 0 (Condition: ExpFlag = 2) + Y <= K: + Y+1 binary digits on left side of '.', K-Y digits on right side + totally requires ((Y+1 - 1) div 4 + 1) + ((K-Y - 1) div 4 + 1) hex digits + Y > K: + Y+1 binary digits on left side, totally ((Y+1 - 1) div 4 + 1) hex digits + case Y<0 (Condition: ExpFlag = 1) 0.XXXX or 0.000XXXX + One digit '0' on left side and K+1+Abs(Y)-1 digits on right side, + totally 1 + ((K+1+Abs(Y)-1-1) div 4 + 1) hex digits. + Compare hdc = hex digit count with MaxHexDigits. If hdc > MaxHexDigits, + goto UseExponent. } + if ExponentI = 0 then + begin + if (Length(Result) > 1) then + Result := '1.' + ToHex(Copy(Result, 2, MaxInt), False); + end + else + begin + if ExpFlag = 1 then + begin + if ExponentI < k then + begin + // No possible that "ExponentI div 4 + (k - ExponentI - 1) div 4 + 2" > MaxHexDigits + tmpS := Copy(Result, 1, ExponentI + 1); + Delete(Result, 1, ExponentI + 1); + Result := ToHex(tmpS, True) + '.' + ToHex(Result, False); + end + else if ExponentI = k then + // 1.01^2 = 101, no ".", no extra "0". + Result := ToHex(Result, True) + else + begin + t := ExponentI div 4 + 1; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Append "0" after Result + Inc(ExponentI); + // Add '0' to Result + SetLength(Result, ExponentI); + for t := k + 2{original Length(Result) + 1} to ExponentI do + Result[t] := '0'; + Result := ToHex(Result, True); + end; + end; + end + else + begin + // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 + t := 2 + (k + ExponentI - 1) div 4; {1 + ((K+1+Abs(Y)-1-1) div 4 + 1)} + if t > MaxHexDigits then + goto UseExponent + else + begin + // Add leading zeroes before Result + SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes + for t := 1 to ExponentI - 1 do + tmpS[t] := '0'; + Result := '0.' + ToHex(tmpS + Result, False); + end; + end; + end; + end; + if Negative then + Result := '-' + Result; + end; +end; + +function FloatDecimalToOctExtended(fIn: Extended; DecimalExp, + AlwaysUseExponent: Boolean): AnsiString; +const + DecToOct: array[0..7] of AnsiChar = + ('0', '1', '2', '3', '4', '5', '6', '7'); + BinPow: array[0..2] of Integer = (4, 2, 1); + + function IntToOct(Int: Integer): AnsiString; + var + k ,t: Integer; + Buf: array[1..10] of AnsiChar; + begin + k := 1; + while (Int <> 0) do + begin + Buf[k] := DecToOct[Int mod 8]; + Inc(k); + Int := Int div 8; + end; + Dec(k); + SetLength(Result, k); + t := 1; + while (k > 0) do + begin + Result[t] := Buf[k]; + Inc(t); + Dec(k); + end; + end; + + function ToOct(const S: AnsiString; LeftToDot: Boolean): AnsiString; + var + i, l, t, m, k: Integer; + Buf: array[1..30] of AnsiChar; + begin + { LeftToDot = True, S will be patched with zeroes on its left side. + For example, S = '110', after patching, S = '0110'. + LeftToDot = False, S will be patched with zeroes on its right side. + S = '110', after patching, S = '1100'. } + l := Length(S); + if LeftToDot then + t := (3 - (l mod 3)) mod 3 + else + t := 0; + i := 1; + m := 1; + k := 0; + while i <= l do + begin + k := k + BinPow[t] * (Ord(S[i]) - Ord('0')); + Inc(t); + if (t = 3) or (i = l) then + begin + Buf[m] := DecToOct[k]; + Inc(m); + k := 0; + t := 0; + end; + Inc(i); + end; + Dec(m); + SetLength(Result, m); + + while (m > 0) do + begin + Result[m] := Buf[m]; + Dec(m); + end; + end; + +var + PConvertData: PConvertFloatSystem; + ConvertData: TConvertFloatSystem; + tmpS: AnsiString; + k, t, i, m: Integer; +label UseExponent; +begin + PConvertData := @ConvertData; + Result := FloatDecimalToBinaryExtended(fIn, True, True, PConvertData); + // See FloatDecimalToBinaryExtended, PConvertData is set to nil when result is definite. + if PConvertData = nil then + Exit; + with ConvertData do + begin + { 3.333D12 // 12 is decimal + 2.22E33 // 33 is octal} + k := Length(Result) - 1; + if AlwaysUseExponent then + begin +UseExponent: + if ExpFlag = 1 then + begin + t := ExponentI div 3; // Exp + i := ExponentI mod 3; // Shift Count + end + else + begin + t := -((ExponentI - 1) div 3 + 1); // Exp + i := (3 - (ExponentI mod 3)) mod 3; // Shift Count + end; + // Get hex digits + if k < i then + begin + // Add extra zeroes + SetLength(Result, i + 1); + for m := k + 2 to i + 1 do + Result[m] := '0'; + Result := ToOct(Result, True); + end + else if k = i then + Result := ToOct(Result, True) + else + begin + tmpS := Copy(Result, 1, i + 1); + Delete(Result, 1, i + 1); + Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); + end; + if t <> 0 then + begin + // Format exponent + if DecimalExp then + Result := Result + 'D' + {$IFDEF UNICODE}AnsiString{$ENDIF}(IntToStr(t)) + else + begin + if ExpFlag = 1 then + Result := Result + 'E' + IntToOct(t) + else // t < 0 + Result := Result + 'E-' + IntToOct(-t); + end; + end; + end + else + begin + if ExponentI = 0 then + begin + if (Length(Result) > 1) then + Result := '1.' + ToOct(Copy(Result, 2, MaxInt), False); + end + else + begin + if ExpFlag = 1 then + begin + if ExponentI < k then + begin + tmpS := Copy(Result, 1, ExponentI + 1); + Delete(Result, 1, ExponentI + 1); + Result := ToOct(tmpS, True) + '.' + ToOct(Result, False); + end + else if ExponentI = k then + // 1.01^2 = 101, no ".", no extra "0". + Result := ToOct(Result, True) + else + begin + t := ExponentI div 3 + 1; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Append "0" after Result + Inc(ExponentI); + // Add '0' to Result + SetLength(Result, ExponentI); + for t := k + 2{original Length(Result) + 1} to ExponentI do + Result[t] := '0'; + Result := ToOct(Result, True); + end; + end; + end + else + begin + // ExpFlag = 2, X.XXXXXXX^Y, Y < 0 + t := 2 + (k + ExponentI - 1) div 3; + if t > MaxHexDigits then + goto UseExponent + else + begin + // Add leading zeroes before Result + SetLength(tmpS, ExponentI - 1); // tmpS stores extra zeroes + for t := 1 to ExponentI - 1 do + tmpS[t] := '0'; + Result := '0.' + ToOct(tmpS + Result, False); + end; + end; + end; + end; + if Negative then + Result := '-' + Result; + end; +end; + +{$ENDIF} +{$ENDIF} + +procedure ExtractFloatSingle(Value: Single; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: Cardinal); +begin + SignNegative := (PCardinal(@Value)^ and CN_SIGN_SINGLE_MASK) <> 0; + Exponent := ((PCardinal(@Value)^ and CN_EXPONENT_SINGLE_MASK) shr 23) - CN_EXPONENT_OFFSET_SINGLE; + Mantissa := PCardinal(@Value)^ and CN_SIGNIFICAND_SINGLE_MASK; + Mantissa := Mantissa or (1 shl 23); // λټӸ 1 +end; + +procedure ExtractFloatDouble(Value: Double; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +begin + SignNegative := (PUInt64(@Value)^ and CN_SIGN_DOUBLE_MASK) <> 0; + Exponent := ((PUInt64(@Value)^ and CN_EXPONENT_DOUBLE_MASK) shr 52) - CN_EXPONENT_OFFSET_DOUBLE; + Mantissa := PUInt64(@Value)^ and CN_SIGNIFICAND_DOUBLE_MASK; + Mantissa := Mantissa or (TUInt64(1) shl 52); // λټӸ 1 +end; + +procedure ExtractFloatExtended(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out Mantissa: TUInt64); +begin + if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then + begin + SignNegative := (PExtendedRec10(@Value)^.ExpSign and CN_SIGN_EXTENDED_MASK) <> 0; + Exponent := (PExtendedRec10(@Value)^.ExpSign and CN_EXPONENT_EXTENDED_MASK) - CN_EXPONENT_OFFSET_EXTENDED; + Mantissa := PExtendedRec10(@Value)^.Mantissa; // 1ü + end + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + ExtractFloatDouble(Value, SignNegative, Exponent, Mantissa) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +procedure ExtractFloatQuadruple(Value: Extended; out SignNegative: Boolean; + out Exponent: Integer; out MantissaLo, MantissaHi: TUInt64); +begin + if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); + + SignNegative := (PCnQuadruple(@Value)^.W1 and CN_SIGN_QUADRUPLE_MASK) <> 0; + Exponent := (PCnQuadruple(@Value)^.W1 and CN_EXPONENT_QUADRUPLE_MASK) - CN_EXPONENT_OFFSET_EXTENDED; + + // Extract 16 Bytes to Mantissas + MantissaLo := PCnQuadruple(@Value)^.Lo; + MantissaHi := TUInt64(PCnQuadruple(@Value)^.Hi0) or (TUInt64(PCnQuadruple(@Value)^.W0) shl 32) or (TUInt64(1) shl 48); // λټӸ 1 +end; + +procedure CombineFloatSingle(SignNegative: Boolean; Exponent: Integer; + Mantissa: Cardinal; var Value: Single); +begin + Mantissa := Mantissa and not (1 shl 23); // ȥ 23 λϵ 1еĻ + PCardinal(@Value)^ := Mantissa and CN_SIGNIFICAND_SINGLE_MASK; + Inc(Exponent, CN_EXPONENT_OFFSET_SINGLE); + + PCardinal(@Value)^ := PCardinal(@Value)^ or (LongWord(Exponent) shl 23); + if SignNegative then + PCardinal(@Value)^ := PCardinal(@Value)^ or CN_SIGN_SINGLE_MASK + else + PCardinal(@Value)^ := PCardinal(@Value)^ and not CN_SIGN_SINGLE_MASK; +end; + +procedure CombineFloatDouble(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Double); +begin + Mantissa := Mantissa and not (TUInt64(1) shl 52); // ȥ 52 λϵ 1еĻ + PUInt64(@Value)^ := Mantissa and CN_SIGNIFICAND_DOUBLE_MASK; + Inc(Exponent, CN_EXPONENT_OFFSET_DOUBLE); + + PUInt64(@Value)^ := PUInt64(@Value)^ or (TUInt64(Exponent) shl 52); + if SignNegative then + PUInt64(@Value)^ := PUInt64(@Value)^ or CN_SIGN_DOUBLE_MASK + else + PUInt64(@Value)^ := PUInt64(@Value)^ and not CN_SIGN_DOUBLE_MASK; +end; + +{$HINTS OFF} + +procedure CombineFloatExtended(SignNegative: Boolean; Exponent: Integer; + Mantissa: TUInt64; var Value: Extended); +var + D: Double; +begin + if (SizeOf(Extended) = CN_EXTENDED_SIZE_10) or (SizeOf(Extended) = CN_EXTENDED_SIZE_16) then + begin + PExtendedRec10(@Value)^.Mantissa := Mantissa; + Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); + + PExtendedRec10(@Value)^.ExpSign := Exponent and CN_EXPONENT_EXTENDED_MASK; + if SignNegative then + PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign or CN_SIGN_EXTENDED_MASK + else + PExtendedRec10(@Value)^.ExpSign := PExtendedRec10(@Value)^.ExpSign and not CN_SIGN_EXTENDED_MASK; + end + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + begin + CombineFloatDouble(SignNegative, Exponent, Mantissa, D); + Value := D; + end + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +{$HINTS ON} + +procedure CombineFloatQuadruple(SignNegative: Boolean; Exponent: Integer; + MantissaLo, MantissaHi: TUInt64; var Value: Extended); +begin + if SizeOf(Extended) <> CN_EXTENDED_SIZE_16 then + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); + + MantissaHi := MantissaHi and not (TUInt64(1) shl 48); // ȥ 112 λϵ 1еĻ + PCnQuadruple(@Value)^.Lo := MantissaLo; + PCnQuadruple(@Value)^.Hi0 := Cardinal(MantissaHi and $FFFFFFFF); + PCnQuadruple(@Value)^.Hi1 := (MantissaHi shr 32) and CN_SIGNIFICAND_QUADRUPLE_MASK; + + Inc(Exponent, CN_EXPONENT_OFFSET_EXTENDED); + PCnQuadruple(@Value)^.W1 := Exponent and CN_EXPONENT_QUADRUPLE_MASK; + if SignNegative then + PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 or CN_SIGN_QUADRUPLE_MASK + else + PCnQuadruple(@Value)^.Hi1 := PCnQuadruple(@Value)^.Hi1 and not CN_SIGN_QUADRUPLE_MASK; +end; + +// UInt64 Ϊ +function UFloat(U: TUInt64): Extended; +{$IFNDEF SUPPORT_UINT64} +var + L, H: Cardinal; +{$ENDIF} +begin +{$IFDEF SUPPORT_UINT64} + Result := U; +{$ELSE} + if U < 0 then // Int64 С 0 ʱ UInt64 Ǵ Int64 ֵ + begin + H := Int64Rec(U).Hi; + L := Int64Rec(U).Lo; + Result := Int64(H) * Int64(CN_MAX_UINT16 + 1); // + Result := Result * (CN_MAX_UINT16 + 1); + Result := Result + L; + end + else + Result := U; +{$ENDIF} +end; + +function UInt64ToSingle(U: TUInt64): Single; +begin + Result := UFloat(U); +end; + +function UInt64ToDouble(U: TUInt64): Double; +begin + Result := UFloat(U); +end; + +function UInt64ToExtended(U: TUInt64): Extended; +begin + Result := UFloat(U); +end; + +// ͨ Trunc ֻܷ Int64 UInt64 +function UTrunc(F: Extended): TUInt64; +var + T: Integer; + SignNeg: Boolean; + Exponent: Integer; + Mantissa: TUInt64; +begin + // õʵָ 1 ͷЧ֣С 1 + ExtractFloatExtended(F, SignNeg, Exponent, Mantissa); + if SignNeg then + raise ERangeError.Create(SRangeError); // ֧ + + // Mantissa 64 λЧ֣С 63 λָС 0 ˵СҪƣôֵ 0 + if Exponent < 0 then + Result := 0 + else + begin + // С Exponent λСߵ + T := 63 - Exponent; // С 0 63 λ 63 λұߣСƺ T λұ + if T < 0 then + raise ERangeError.Create(SRangeError); // Exponent ̫ + + Result := Mantissa shr T; + end; +end; + +function SingleToUInt64(F: Single): TUInt64; +begin + Result := UTrunc(F); +end; + +function DoubleToUInt64(F: Double): TUInt64; +begin + Result := UTrunc(F); +end; + +function ExtendedToUInt64(F: Extended): TUInt64; +begin + Result := UTrunc(F); +end; + +function SingleIsInfinite(AValue: Single): Boolean; +begin + Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and + ((PCardinal(@AValue)^ and $007FFFFF) = $00000000); +end; + +function DoubleIsInfinite(AValue: Double): Boolean; +begin + Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and + ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) = $0000000000000000); +end; + +function ExtendedIsInfinite(AValue: Extended): Boolean; +begin + if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then + Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and + ((PExtendedRec10(@AValue)^.Mantissa) = 0) + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + Result := DoubleIsInfinite(AValue) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +function SingleIsNan(AValue: Single): Boolean; +begin + Result := ((PCardinal(@AValue)^ and $7F800000) = $7F800000) and + ((PCardinal(@AValue)^ and $007FFFFF) <> $00000000); +end; + +function DoubleIsNan(AValue: Double): Boolean; +begin + Result := ((PUInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and + ((PUInt64(@AValue)^ and $000FFFFFFFFFFFFF) <> $0000000000000000); +end; + +function ExtendedIsNan(AValue: Extended): Boolean; +begin + if SizeOf(Extended) = CN_EXTENDED_SIZE_10 then + Result := ((PExtendedRec10(@AValue)^.ExpSign and $7FFF) = $7FFF) and + ((PExtendedRec10(@AValue)^.Mantissa and $7FFFFFFFFFFFFFFF) <> 0) + else if SizeOf(Extended) = CN_EXTENDED_SIZE_8 then + Result := DoubleIsNan(AValue) + else + raise ECnFloatSizeError.Create(SCN_ERROR_EXTENDED_SIZE); +end; + +end. diff --git a/CnPack/Crypto/CnKDF.dcu b/CnPack/Crypto/CnKDF.dcu new file mode 100644 index 0000000000000000000000000000000000000000..ab8a24ef0bda87b06579270c031782ff29ce117e GIT binary patch literal 13854 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

GjU1lO-!A@MOz*mL zk-Gj!-RqIMz67tk4skxc*I|n>dmVNPQe>KCjM`HsD%@3flg^&Dvi^!w+b8c};+RtI?`sDq~mozdF9E(z)B^q_;Pr50Yd@w&7R z8H$M3nEMFY0*=QnVorAJx|L{6Fg+< z7;|^UJ08+Il8Fbf3+yXbx}voM`Q>wuO{fDM?E@KY7bev66Yeu@KZvR#T%)~!64hci z79&rggoBMp<3FI2(lEa6_=6Mf-t^9qaT4Ykg0e)E6~1C})eE=5R;yH2iT5g85?0WXyV2pxeT?4D8&@ zvvpo)4{iR!L8QS9&iLOaEn4FCP4aa3@0175PT|@ z;lQyp9#Ohu;fU@&ZZy>M*Qo<-dAr-+WNo>)k5rx>Q26=5inSTp^Ok_RrsI`?l9+m& zugS$L66HYW*@QDE)FGZ|`qMkNAjXYF?FGg}LmKfiXb64Cg~T!FGQvE#gsbj3(~U$# z%YT?Ek;BLN`xJlo@b?-1?&a@S=`HR9JRG}JpsQ{4BMs}BW0bWilt@Q9+UILkXGeR6 zR&~%J_bwbdoa`=s)NRL!fV7(2Cr0fl9#q(~Po3x(mDBJ25IJySap#Lzu%F|h9f>^k zA3MTxoM%DRz5ihiXWndY?7o&uQjA_O~?dh=4sVNc5(aBhj0t>FT2nr1g zzHig897SdVJ&xr9>|fi)g?_g&CK)@?%XoXR^Ic@F{D4q}z)^!;FjCp95E3taBKW zlkG(`j826K*Tqs{EY3|d7M-0bM$HhYJp}?zZ^iJ9>Cz}&E_cn0su{S}#FHs9o#RKc z183cHR?&B8+7xWJs^= zS6Gl-%zK6XI`v%o{p2d~DL*Wxd^4sO!m|(0V|ZS`(~n0x9uDw*nd`}}0Cn1ROq=gC|#35~lGT;1ZghXDFj035(G zjE5!TA2smg;DKLZ=J@DISozDieVf}?$8?h#B8y|4nkfy^tXQXJLY;(D0{j$9DB_4K z7oh`*eeUxmU3N*wmwvAn1TDa`7tc{Vr}3P}lWZgF33TxwAmzfkA_xq=76b;Lff|L12g^1VLN`L12g^1c4!GQh&v<>_1YZ--XuuI3FT+} zob43n>~rFrjpIZ75pm;#fgpI83i0df~7W!ROF;4bThM>`~qaC+JzI zLsX|g4EfZ=91$M~aSA^liqS+*e9(-%CMaC(5K`O#9(;tUp2Nda9zNDYK%Ljqr*ZJI z0c{N59ZbHbsgCJR-*3>Ttadhmq`=rq9am9dc?p@3&6+dK*JIGle`aZA{GSQ&4ac_M z!|_L%Ji1yQUCTaU@+Yh1Pu8+ACXcO_$ExtHmOQ>(9&ce5d>3VrT(TlLP>N@_O}5$O zRGYlZCfjZDOq=Ym$+K;8hE1MllbtsCPMds(O}=Y6!xwDmxdc6J@{U}VhGxjd=89s0 zD6*xEY=v}#yg~{n`3_~(Y-PDaxpuy?e4etZSSg>U6fKq)NU6%|OsGj!x>A*j`AX$t zWz|Am+^H;|sT9pq4pk^cmCEvkdVTFQGS5M#l*`Olo?E9Bg#Wd%! z1J(lhfHhy|AFvt*!RkF}El^&wI`ECbwGhZ)uc6)OkYBUrDw`KiUMVL*KWohdd(s$Z z0qv}A$|(r70T)6%+C@5EQOSh;qo^4Ln{vDMRZo>{3pGlf&3T)Rr?E>gOu=bS83PEOBxai#Ji zmNYS7H3!O5ii(95DnyY#4Sbps%#))$1{cdwp2<))7bxBQeUiUl+;N#+OO+yo#Y+8e z-Q~p~Q>6bby^Pp=rN~9@s{Q3EMQbl3`Ppa-&?~{QGuci#2Tmvcwtqc}-eP$*aeIaLK=P$a%N5w#pBo3^$|9cy8q=T?)I{Cn%D-*cb}? z{cIe??4#HXP&$W@*HNy%iKR$M605Kwv7?Q0E|qI-Yyp+)Z4CbwE3u7~-%-|B>?}r= zXKE#6QB- +================================================================================ +* ƣ +* ԪƣԿ㷨KDFԪ +* ԪߣCnPack (master@cnpack.org) +* עԪʵ˻ RFC2898 PBKDF1 PBKDF2 Կ㷨 PBKDF1 ֧ MD2 㷨 +* ͬʱҲʵ˻ RFC5869 HKDF HMac Կ㷨 +* SM2/SM9 㷨й涨㷨 +* ƽ̨WinXP + Delphi 5.0 +* ݲԣδ +* õԪ豾ػ +* ޸ļ¼2025.01.09 V1.5 +* HKDF ʵֺ +* 2022.06.21 V1.4 +* ϲһֽ CnSM2SM9KDF AnsiString ڸ߰汾 Delphi ¿ +* 2022.04.26 V1.3 +* ޸ LongWord Integer ַת֧ MacOS64 +* 2022.01.02 V1.2 +* CnPBKDF2 һԼ Unicode µļ +* 2021.11.25 V1.1 +* CnSM2KDF Unicode µļ +* 2020.03.30 V1.0 +* Ԫ CnPemUtils ж +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnMD5, CnSHA1, CnSHA2, CnSHA3, CnSM3; + +type + TCnKeyDeriveHash = (ckdMd5, ckdSha256, ckdSha1); + {* CnGetDeriveKey ʹõӴշ} + + TCnPBKDF1KeyHash = (cpdfMd2, cpdfMd5, cpdfSha1); + {* PBKDF1 涨Ӵշ MD2 Dz֧} + + TCnPBKDF2KeyHash = (cpdfSha1Hmac, cpdfSha256Hmac); + {* PBKDF2 涨Ӵշ} + + TCnHKDFHash = (chkMd5, chkSha1, chkSha256, chkSha3_256, chkSm3); + {* HKDFHMAC-based Key Derivation Functionֵ֧Ӵ} + + ECnKDFException = class(Exception); + {* KDF 쳣} + +function CnGetDeriveKey(const Password: AnsiString; const Salt: AnsiString; + OutKey: PAnsiChar; KeyLength: Cardinal; KeyHash: TCnKeyDeriveHash = ckdMd5): Boolean; +{* Openssl е BytesToKeyָӴ㷨ɼ Key + Ŀǰ KeyLength ֧ HashҲ MD5 32 ֽڣSHA256 64 ֽڡ + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + OutKey: PAnsiChar - Կݿַ + KeyLength: Cardinal - Կݿֽڳ + KeyHash: TCnKeyDeriveHash - Ӵ㷨 + + ֵBoolean - Ƿɳɹ +} + +function CnPBKDF1(const Password: AnsiString; const Salt: AnsiString; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): AnsiString; +{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪ AnsiString + DerivedKeyByteLength Կֽȹ̶ + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 + + ֵAnsiString - ɵԿ +} + +function CnPBKDF2(const Password: AnsiString; const Salt: AnsiString; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): AnsiString; +{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪ AnsiString + DerivedKeyByteLength Կֽȿɱ䣬 + + + const Password: AnsiString - + const Salt: AnsiString - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 + + ֵAnsiString - ɵԿ +} + +function CnPBKDF1Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; +{* Password Based KDF 1 ʵ֣򵥵Ĺ̶Ӵյֻ֧ MD5 SHA1뷵ֵΪֽ顣 + DerivedKeyByteLength Կֽȹ̶ + + + const Password: TBytes - + const Salt: TBytes - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF1KeyHash - Ӵ㷨 + + ֵTBytes - ɵԿ +} + +function CnPBKDF2Bytes(const Password: TBytes; const Salt: TBytes; Count: Integer; + DerivedKeyByteLength: Integer; KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; +{* Password Based KDF 2 ʵ֣ HMAC-SHA1 HMAC-SHA256뷵ֵΪֽ顣 + DerivedKeyByteLength Կֽȿɱ䣬 + + + const Password: TBytes - + const Salt: TBytes - ֵ + Count: Integer - + DerivedKeyByteLength: Integer - ɵԿֽڳ + KeyHash: TCnPBKDF2KeyHash - Ӵ㷨 + + ֵTBytes - ɵԿ +} + +// ============ SM2/SM9 й涨ͬһԿַװʵ =============== + +function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; +{* SM2 Բ߹Կ㷨й涨ԿDerivedKeyLength Կֽ + AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF + + + const Data: AnsiString - Կԭʼݣ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵAnsiString - ɵԿ +} + +function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; +{* SM9 ʶ㷨й涨ԿDerivedKeyLength Կֽ + AnsiStringͬʱƺҲû SharedInfo ANSI-X9.63-KDF + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵAnsiString - ɵԿ +} + +function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +{* Ϊֽʽ SM2 Բ߹Կ㷨й涨Կ + DerivedKeyLength Կֽɵֽ顣 + + + const Data: TBytes - Կԭʼݵֽ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; +{* Ϊڴʽ SM9 ʶ㷨й涨Կ + DerivedKeyLength Կֽɵֽ顣 + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; overload; +{* Ϊֽʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ + DerivedKeyLength ԿֽɵԿֽ顣 + + + Data: TBytes - Կԭʼݵֽ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; +{* Ϊڴʽ SM2 Բ߹Կ㷨 SM9 ʶ㷨й涨Կ + DerivedKeyLength ԿֽԿֽ顣 + + + Data: Pointer - Կԭʼݿַ + DataByteLen: Integer - Կԭʼݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; + Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; + DerivedKeyByteLength: Integer): TBytes; overload; +{* HMAC KDF Կ IKMSalt InfoָȵԿ + Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ + + + HKDF: TCnHKDFHash - Ӵ㷨 + IKM: Pointer - ԿݣInput Keying Materialַ + IKMByteLen: Integer - Կݵֽڳ + Salt: Pointer - Կֵݿַ + SaltByteLen: Integer - Կֵݵֽڳ + Info: Pointer - ԿĿѡϢݿַ + InfoByteLen: Integer - ԿĿѡϢݵֽڳ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; + DerivedKeyByteLength: Integer): TBytes; overload; +{* HMAC KDF Կ IKMSalt Info ֽ飬ָȵԿ + Salt Ϊգڲʹù̶Ӵսȵȫ 0Info ΪաɵԿ + + HKDF: TCnHKDFHash - Ӵ㷨 + IKM: TBytes - Կ + Salt: TBytes - Կֵ + Info: TBytes - ԿĿѡϢ + DerivedKeyByteLength: Integer - ɵԿֽڳ + + ֵTBytes - ɵԿ +} + +implementation + +resourcestring + SCnErrorKDFKeyTooLong = 'Derived Key Too Long.'; + SCnErrorKDFParam = 'Invalid Parameters.'; + SCnErrorKDFHashNOTSupport = 'Hash Method NOT Support.'; + +function Min(A, B: Integer): Integer; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + if A < B then + Result := A + else + Result := B; +end; + +function CnGetDeriveKey(const Password, Salt: AnsiString; OutKey: PAnsiChar; KeyLength: Cardinal; + KeyHash: TCnKeyDeriveHash): Boolean; +var + Md5Dig, Md5Dig2: TCnMD5Digest; + Sha256Dig, Sha256Dig2: TCnSHA256Digest; + SaltBuf, PS, PSMD5, PSSHA256: AnsiString; +begin + Result := False; + + if (Password = '') or (OutKey = nil) or (KeyLength < 8) then + Exit; + + SetLength(SaltBuf, 8); + FillChar(SaltBuf[1], Length(SaltBuf), 0); + if Salt <> '' then + Move(Salt[1], SaltBuf[1], Min(Length(Salt), 8)); + + if not (KeyHash in [ckdMd5, ckdSha256]) then + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + + PS := AnsiString(Password) + SaltBuf; // 涨ǰ 8 ֽΪ Salt + if KeyHash = ckdMd5 then + begin + SetLength(PSMD5, SizeOf(TCnMD5Digest) + Length(PS)); + Move(PS[1], PSMD5[SizeOf(TCnMD5Digest) + 1], Length(PS)); + Md5Dig := MD5StringA(PS); + // Salt ƴ MD5 16 ByteΪһ + + Move(Md5Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); + if KeyLength <= SizeOf(TCnMD5Digest) then + begin + Result := True; + Exit; + end; + + KeyLength := KeyLength - SizeOf(TCnMD5Digest); + OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnMD5Digest)); + + Move(Md5Dig[0], PSMD5[1], SizeOf(TCnMD5Digest)); + Md5Dig2 := MD5StringA(PSMD5); + Move(Md5Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnMD5Digest))); + if KeyLength <= SizeOf(TCnMD5Digest) then + Result := True; + + // KeyLength ̫㲻 + end + else if KeyHash = ckdSha256 then + begin + SetLength(PSSHA256, SizeOf(TCnSHA256Digest) + Length(PS)); + Move(PS[1], PSSHA256[SizeOf(TCnSHA256Digest) + 1], Length(PS)); + Sha256Dig := SHA256StringA(PS); + // Salt ƴ SHA256 32 ByteΪһ + + Move(Sha256Dig[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); + if KeyLength <= SizeOf(TCnSHA256Digest) then + begin + Result := True; + Exit; + end; + + KeyLength := KeyLength - SizeOf(TCnSHA256Digest); + OutKey := PAnsiChar(TCnNativeInt(OutKey) + SizeOf(TCnSHA256Digest)); + + Move(Sha256Dig[0], PSSHA256[1], SizeOf(TCnSHA256Digest)); + Sha256Dig2 := SHA256StringA(PSSHA256); + Move(Sha256Dig2[0], OutKey^, Min(KeyLength, SizeOf(TCnSHA256Digest))); + if KeyLength <= SizeOf(TCnSHA256Digest) then + Result := True; + + // KeyLength ̫㲻 + end; +end; + +(* + T_1 = Hash (P || S) , + T_2 = Hash (T_1) , + ... + T_c = Hash (T_{c-1}) , + DK = Tc<0..dkLen-1> +*) +function CnPBKDF1(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF1KeyHash): AnsiString; +var + P, S, Res: TBytes; +begin + P := AnsiToBytes(Password); + S := AnsiToBytes(Salt); + Res := CnPBKDF1Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); + Result := BytesToAnsi(Res); +end; + +{ + DK = T1 + T2 + ... + Tdklen/hlen + Ti = F(Password, Salt, c, i) + + F(Password, Salt, c, i) = U1 ^ U2 ^ ... ^ Uc + + U1 = PRF(Password, Salt + INT_32_BE(i)) + U2 = PRF(Password, U1) + ... + Uc = PRF(Password, Uc-1) +} +function CnPBKDF2(const Password, Salt: AnsiString; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF2KeyHash): AnsiString; +var + P, S, Res: TBytes; +begin + P := AnsiToBytes(Password); + S := AnsiToBytes(Salt); + Res := CnPBKDF2Bytes(P, S, Count, DerivedKeyByteLength, KeyHash); + Result := BytesToAnsi(Res); +end; + +function CnPBKDF1Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF1KeyHash = cpdfMd5): TBytes; +var + I: Integer; + Md5Dig, TM: TCnMD5Digest; + Sha1Dig, TS: TCnSHA1Digest; + Ptr: PAnsiChar; +begin + Result := nil; + if (Password = nil) or (Count <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + case KeyHash of + cpdfMd5: + begin + if DerivedKeyByteLength > SizeOf(TCnMD5Digest) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + SetLength(Result, DerivedKeyByteLength); + Md5Dig := MD5Bytes(ConcatBytes(Password, Salt)); // Got T1 + if Count > 1 then + begin + Ptr := PAnsiChar(@TM[0]); + for I := 2 to Count do + begin + TM := Md5Dig; + Md5Dig := MD5Buffer(Ptr, SizeOf(TCnMD5Digest)); // Got T_c + end; + end; + + Move(Md5Dig[0], Result[0], DerivedKeyByteLength); + end; + cpdfSha1: + begin + if DerivedKeyByteLength > SizeOf(TCnSHA1Digest) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + SetLength(Result, DerivedKeyByteLength); + Sha1Dig := SHA1Bytes(ConcatBytes(Password, Salt)); // Got T1 + if Count > 1 then + begin + Ptr := PAnsiChar(@TS[0]); + for I := 2 to Count do + begin + TS := Sha1Dig; + Sha1Dig := SHA1Buffer(Ptr, SizeOf(TCnSHA1Digest)); // Got T_c + end; + end; + + Move(Sha1Dig[0], Result[0], DerivedKeyByteLength); + end; + else + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + end; +end; + +function CnPBKDF2Bytes(const Password, Salt: TBytes; Count, DerivedKeyByteLength: Integer; + KeyHash: TCnPBKDF2KeyHash = cpdfSha1Hmac): TBytes; +var + HLen, D, I, J, K: Integer; + Sha1Dig1, Sha1Dig, T1: TCnSHA1Digest; + Sha256Dig1, Sha256Dig, T256: TCnSHA256Digest; + S, S1, S256, Pad: TBytes; + PAddr: Pointer; +begin + Result := nil; + if (Salt = nil) or (Count <= 0) or (DerivedKeyByteLength <=0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + if (Password = nil) or (Length(Password) = 0) then + PAddr := nil + else + PAddr := @Password[0]; + + case KeyHash of + cpdfSha1Hmac: + HLen := 20; + cpdfSha256Hmac: + HLen := 32; + else + raise ECnKDFException.Create(SCnErrorKDFParam); + end; + + D := (DerivedKeyByteLength div HLen) + 1; + SetLength(S1, SizeOf(TCnSHA1Digest)); + SetLength(S256, SizeOf(TCnSHA256Digest)); + + SetLength(Pad, 4); + if KeyHash = cpdfSha1Hmac then + begin + for I := 1 to D do + begin + Pad[0] := I shr 24; + Pad[1] := I shr 16; + Pad[2] := I shr 8; + Pad[3] := I; + S := ConcatBytes(Salt, Pad); + + SHA1Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha1Dig1); + T1 := Sha1Dig1; + + for J := 2 to Count do + begin + SHA1Hmac(PAddr, Length(Password), PAnsiChar(@T1[0]), SizeOf(TCnSHA1Digest), Sha1Dig); + T1 := Sha1Dig; + for K := Low(TCnSHA1Digest) to High(TCnSHA1Digest) do + Sha1Dig1[K] := Sha1Dig1[K] xor T1[K]; + end; + + Move(Sha1Dig1[0], S1[0], Length(S1)); + Result := ConcatBytes(Result, S1); + end; + Result := Copy(Result, 0, DerivedKeyByteLength); + end + else if KeyHash = cpdfSha256Hmac then + begin + for I := 1 to D do + begin + Pad[0] := I shr 24; + Pad[1] := I shr 16; + Pad[2] := I shr 8; + Pad[3] := I; + S := ConcatBytes(Salt, Pad); + + SHA256Hmac(PAddr, Length(Password), PAnsiChar(@S[0]), Length(S), Sha256Dig1); + T256 := Sha256Dig1; + + for J := 2 to Count do + begin + SHA256Hmac(PAddr, Length(Password), PAnsiChar(@T256[0]), SizeOf(TCnSHA256Digest), Sha256Dig); + T256 := Sha256Dig; + for K := Low(TCnSHA256Digest) to High(TCnSHA256Digest) do + Sha256Dig1[K] := Sha256Dig1[K] xor T256[K]; + end; + + Move(Sha256Dig1[0], S256[0], SizeOf(TCnSHA256Digest)); + Result := ConcatBytes(Result, S256); + end; + Result := Copy(Result, 0, DerivedKeyByteLength); + end; +end; + +function CnSM2KDF(const Data: AnsiString; DerivedKeyByteLength: Integer): AnsiString; +var + Res: TBytes; +begin + if (Data = '') or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + Res := CnSM2SM9KDF(@Data[1], Length(Data), DerivedKeyByteLength); + Result := BytesToAnsi(Res); +end; + +function CnSM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): AnsiString; +var + Res: TBytes; +begin + Res := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); + Result := BytesToAnsi(Res); +end; + +function CnSM2KDFBytes(const Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +begin + Result := CnSM2SM9KDF(Data, DerivedKeyByteLength); +end; + +function CnSM9KDFBytes(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; +begin + Result := CnSM2SM9KDF(Data, DataByteLen, DerivedKeyByteLength); +end; + +function CnSM2SM9KDF(Data: TBytes; DerivedKeyByteLength: Integer): TBytes; +begin + if (Data = nil) or (Length(Data) <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + Result := CnSM2SM9KDF(@Data[0], Length(Data), DerivedKeyByteLength); +end; + +function CnSM2SM9KDF(Data: Pointer; DataByteLen: Integer; DerivedKeyByteLength: Integer): TBytes; overload; +var + DArr: TBytes; + CT, SCT: Cardinal; + I, CeilLen: Integer; + IsInt: Boolean; + SM3D: TCnSM3Digest; +begin + Result := nil; + if (Data = nil) or (DataByteLen <= 0) or (DerivedKeyByteLength <= 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + DArr := nil; + CT := 1; + + try + SetLength(DArr, DataByteLen + SizeOf(Cardinal)); + Move(Data^, DArr[0], DataByteLen); + + IsInt := DerivedKeyByteLength mod SizeOf(TCnSM3Digest) = 0; + CeilLen := (DerivedKeyByteLength + SizeOf(TCnSM3Digest) - 1) div SizeOf(TCnSM3Digest); + + SetLength(Result, DerivedKeyByteLength); + for I := 1 to CeilLen do + begin + SCT := UInt32HostToNetwork(CT); // Ȼĵû˵Ҫһ + Move(SCT, DArr[DataByteLen], SizeOf(Cardinal)); + SM3D := SM3(@DArr[0], Length(DArr)); + + if (I = CeilLen) and not IsInt then + begin + // һ 32 ʱֻƶһ + Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], (DerivedKeyByteLength mod SizeOf(TCnSM3Digest))); + end + else + Move(SM3D[0], Result[(I - 1) * SizeOf(TCnSM3Digest)], SizeOf(TCnSM3Digest)); + + Inc(CT); + end; + finally + SetLength(DArr, 0); + end; +end; + +function CnHKDF(HKDF: TCnHKDFHash; IKM: Pointer; IKMByteLen: Integer; + Salt: Pointer; SaltByteLen: Integer; Info: Pointer; InfoByteLen: Integer; + DerivedKeyByteLength: Integer): TBytes; +const + MAX_BYTE = 255; +var + PRKMd5, Md5T: TCnMD5Digest; + PRKSha1, Sha1T: TCnSHA1Digest; + PRKSha256, Sha256T: TCnSHA256Digest; + PRKSha3256, Sha3256T: TCnSHA3_256Digest; + PRKSm3, Sm3T: TCnSM3Digest; + T0, T: TBytes; + N, I, Start, HashLen: Integer; +begin + if IKM = nil then + IKMByteLen := 0; + + if Salt = nil then + SaltByteLen := 0; + + if Info = nil then + InfoByteLen := 0; + + if (IKMByteLen < 0) or (SaltByteLen < 0) or (InfoByteLen < 0) then + raise ECnKDFException.Create(SCnErrorKDFParam); + + // Extract HMac(Salt, IKM)ע IKM ݣ HMac Key + case HKDF of + chkMd5: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnMD5Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnMD5Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKMd5[0], HashLen, 0); + MD5Hmac(@PRKMd5[0], HashLen, IKM, IKMByteLen, PRKMd5); + end + else + MD5Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKMd5); + end; + chkSha1: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA1Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA1Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha1[0], HashLen, 0); + SHA1Hmac(@PRKSha1[0], HashLen, IKM, IKMByteLen, PRKSha1); + end + else + SHA1Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha1); + end; + chkSha256: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA256Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA256Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha256[0], HashLen, 0); + SHA256Hmac(@PRKSha256[0], HashLen, IKM, IKMByteLen, PRKSha256); + end + else + SHA256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha256); + end; + chkSha3_256: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSHA3_256Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSHA3_256Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSha3256[0], HashLen, 0); + SHA3_256Hmac(@PRKSha3256[0], HashLen, IKM, IKMByteLen, PRKSha3256); + end + else + SHA3_256Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSha3256); + end; + chkSm3: + begin + if (DerivedKeyByteLength <= 0) or (DerivedKeyByteLength > MAX_BYTE * SizeOf(TCnSM3Digest)) then + raise ECnKDFException.Create(SCnErrorKDFKeyTooLong); + + HashLen := SizeOf(TCnSM3Digest); + if (Salt = nil) or (SaltByteLen <= 0) then + begin + FillChar(PRKSm3[0], HashLen, 0); + SM3Hmac(@PRKSm3[0], HashLen, IKM, IKMByteLen, PRKSm3); + end + else + SM3Hmac(Salt, SaltByteLen, IKM, IKMByteLen, PRKSm3); + end; + else + raise ECnKDFException.Create(SCnErrorKDFHashNOTSupport); + end; + + // ʼ Expand + SetLength(T0, InfoByteLen + 1); + if InfoByteLen > 0 then + Move(Info^, T0[0], InfoByteLen); + T0[InfoByteLen] := 1; // ƴװ T0 + + // ʼÿֵļ + SetLength(T, HashLen + InfoByteLen + 1); + + // ýȲ + N := (DerivedKeyByteLength + HashLen - 1) div HashLen; + SetLength(Result, DerivedKeyByteLength); + + // T0 һ T1 + case HKDF of + chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T0[0], Length(T0), Md5T); + chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T0[0], Length(T0), Sha1T); + chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T0[0], Length(T0), Sha256T); + chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T0[0], Length(T0), Sha3256T); + chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T0[0], Length(T0), Sm3T); + end; + + Start := 0; + for I := 1 to N do + begin + // T1 ƴڽ + if DerivedKeyByteLength > HashLen then + begin + case HKDF of + chkMd5: Move(Md5T[0], Result[Start], HashLen); + chkSha1: Move(Sha1T[0], Result[Start], HashLen); + chkSha256: Move(Sha256T[0], Result[Start], HashLen); + chkSha3_256: Move(Sha3256T[0], Result[Start], HashLen); + chkSm3: Move(Sm3T[0], Result[Start], HashLen); + end; + Inc(Start, HashLen); + Dec(DerivedKeyByteLength, HashLen); + end + else + begin + case HKDF of + chkMd5: Move(Md5T[0], Result[Start], DerivedKeyByteLength); + chkSha1: Move(Sha1T[0], Result[Start], DerivedKeyByteLength); + chkSha256: Move(Sha256T[0], Result[Start], DerivedKeyByteLength); + chkSha3_256: Move(Sha3256T[0], Result[Start], DerivedKeyByteLength); + chkSm3: Move(Sm3T[0], Result[Start], DerivedKeyByteLength); + end; + Break; + end; + + // T1 Info ƴһ𲢼һ + case HKDF of + chkMd5: Move(Md5T[0], T[0], HashLen); + chkSha1: Move(Sha1T[0], T[0], HashLen); + chkSha256: Move(Sha256T[0], T[0], HashLen); + chkSha3_256: Move(Sha3256T[0], T[0], HashLen); + chkSm3: Move(Sm3T[0], T[0], HashLen); + end; + Move(Info^, T[HashLen], InfoByteLen); + T[HashLen + InfoByteLen] := I + 1; + + // Ӵ T2 T1 + case HKDF of + chkMd5: MD5Hmac(@PRKMd5[0], HashLen, @T[0], Length(T), Md5T); + chkSha1: SHA1Hmac(@PRKSha1[0], HashLen, @T[0], Length(T), Sha1T); + chkSha256: SHA256Hmac(@PRKSha256[0], HashLen, @T[0], Length(T), Sha256T); + chkSha3_256: SHA3_256Hmac(@PRKSha3256[0], HashLen, @T[0], Length(T), Sha3256T); + chkSm3: SM3Hmac(@PRKSm3[0], HashLen, @T[0], Length(T), Sm3T); + end; + end; +end; + +function CnHKDFBytes(HKDF: TCnHKDFHash; IKM: TBytes; Salt: TBytes; Info: TBytes; + DerivedKeyByteLength: Integer): TBytes; +var + IKMP, SaltP, InfoP: Pointer; + IKML, SaltL, InfoL: Integer; +begin + IKMP := nil; + SaltP := nil; + InfoP := nil; + IKML := 0; + SaltL := 0; + InfoL := 0; + + if Length(IKM) > 0 then + begin + IKMP := @IKM[0]; + IKML := Length(IKM); + end; + if Length(Salt) > 0 then + begin + SaltP := @Salt[0]; + SaltL := Length(Salt); + end; + if Length(Info) > 0 then + begin + InfoP := @Info[0]; + InfoL := Length(Info); + end; + + Result := CnHKDF(HKDF, IKMP, IKML, SaltP, SaltL, InfoP, InfoL, DerivedKeyByteLength); +end; + +end. diff --git a/CnPack/Crypto/CnMD5.dcu b/CnPack/Crypto/CnMD5.dcu new file mode 100644 index 0000000000000000000000000000000000000000..cb8d6620407415739e0d60166eaf5935ca4734ae GIT binary patch literal 15598 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 WtWPF_AP}eC1XBtgT&1reuKxu#%R$fp literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnMD5.pas b/CnPack/Crypto/CnMD5.pas new file mode 100644 index 0000000..e859993 --- /dev/null +++ b/CnPack/Crypto/CnMD5.pas @@ -0,0 +1,884 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +{******************************************************************************} +{ } +{ MD5 Message-Digest for Delphi 4 } +{ } +{ Delphi 4 Unit implementing the } +{ RSA Data Security, Inc. MD5 Message-Digest Algorithm } +{ } +{ Implementation of Ronald L. Rivest's RFC 1321 } +{ } +{ Copyright ?1997-1999 Medienagentur Fichtner & Meyer } +{ Written by Matthias Fichtner } +{ } +{ -----------------------------------------------------------------------------} +{ See RFC 1321 for RSA Data Security's copyright and license notice! } +{ -----------------------------------------------------------------------------} +{ The latest release of md5.pas will always be available from } +{ the distribution site at: http://www.fichtner.net/delphi/md5/ } +{ -----------------------------------------------------------------------------} +{ Please send questions, bug reports and suggestions } +{ regarding this code to: mfichtner@fichtner-meyer.com } +{ -----------------------------------------------------------------------------} +{ This code is provided "as is" without express or } +{ implied warranty of any kind. Use it at your own risk. } +{******************************************************************************} + +unit CnMD5; +{* |

+================================================================================
+* ƣ
+* ԪƣMD5 Ӵ㷨ʵֵԪ
+* Ԫߣ壨QSoft hq.com@263.net; http://qsoft.51.net
+*            Ronald L. Rivest  MD5.pas дԭʼ
+*     עԪʵ MD5 Ӵ㷨Ӧ HMAC 㷨
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2019.12.12 V1.4
+*               ֧ TBytes
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS
+*           2014.11.14 V1.2
+*               л Pascal ֿ֧ƽ̨
+*           2003.09.18 V1.1
+*               òҵ˸õԪԭߵİȨ
+*           2003.09.18 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnConsts, CnNative {$IFDEF MSWINDOWS}, Windows {$ENDIF}; + +type + PMD5Digest = ^TCnMD5Digest; + TCnMD5Digest = array[0..15] of Byte; + {* MD5 Ӵս16 ֽ} + + TCnMD5Count = array[0..1] of Cardinal; + TCnMD5State = array[0..3] of Cardinal; + TCnMD5Block = array[0..15] of Cardinal; + + TCnMD5Buffer = array[0..63] of Byte; + + TCnMD5Context = record + {* MD5 Ľṹ} + State : TCnMD5State; + Count : TCnMD5Count; + Buffer : TCnMD5Buffer; + Ipad : array[0..63] of Byte; {!< HMAC: inner padding } + Opad : array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnMD5CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* Ȼص¼} + +//---------------------------------------------------------------- +// û API +//---------------------------------------------------------------- + +function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; +{* ݿ MD5 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; +{* ݿ MD5 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Bytes(Data: TBytes): TCnMD5Digest; +{* ֽ MD5 㡣 + + + Data: TBytes - ֽ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5String(const Str: string): TCnMD5Digest; +{* String ݽ MD5 㡣ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + + const Str: string - ַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5StringA(const Str: AnsiString): TCnMD5Digest; +{* AnsiString ݽ MD5 㣬ֱӼڲݣޱ봦 + + + const Str: AnsiString - ַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5StringW(const Str: WideString): TCnMD5Digest; +{* WideString ַת MD5 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$IFDEF UNICODE} + +function MD5UnicodeString(const Str: string): TCnMD5Digest; +{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$ELSE} + +function MD5UnicodeString(const Str: WideString ): TCnMD5Digest; +{* UnicodeString ݽֱӵ MD5 㣬ֱӼڲ UTF16 ݣת + + + + const Str: WideString - Ŀַ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +{$ENDIF} + +function MD5File(const FileName: string; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +{* ָļݽ MD5 㡣 + + + const FileName: string - ļ + CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +function MD5Stream(Stream: TStream; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +{* ָݽ MD5 㡣 + + + Stream: TStream - + CallBack: TCnMD5CalcProgressFunc - ȻصĬΪ + + ֵTCnMD5Digest - ص MD5 Ӵֵ +} + +// ⲿݽɢ MD5 㣬MD5Update ɶα + +procedure MD5Init(var Context: TCnMD5Context); +{* ʼһ MD5 ģ׼ MD5 + + + var Context: TCnMD5Context - ʼ MD5 + + ֵޣ +} + +procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ MD5 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnMD5Context - MD5 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); +{* ּ㣬 MD5 Digest С + + + var Context: TCnMD5Context - MD5 + var Digest: TCnMD5Digest - ص MD5 Ӵֵ + + ֵޣ +} + +function MD5Print(const Digest: TCnMD5Digest): string; +{* ʮƸʽ MD5 Ӵֵ + + + const Digest: TCnMD5Digest - ָ MD5 Ӵֵ + + ֵstring - ʮַ +} + +function MD5Match(const D1: TCnMD5Digest; const D2: TCnMD5Digest): Boolean; +{* Ƚ MD5 ӴֵǷȡ + + + const D1: TCnMD5Digest - Ƚϵ MD5 Ӵֵһ + const D2: TCnMD5Digest - Ƚϵ MD5 Ӵֵ + + ֵBoolean - Ƿ +} + +function MD5DigestToStr(const Digest: TCnMD5Digest): string; +{* MD5 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnMD5Digest - ת MD5 Ӵֵ + + ֵstring - صַ +} + +procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnMD5Digest); +{* MD5 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - MD5 Կݿַ + KeyByteLength: Integer - MD5 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnMD5Digest - ص MD5 Ӵֵ + + ֵޣ +} + +implementation + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_MD5_BLOCK_SIZE_BYTE = 64; + HMAC_MD5_OUTPUT_LENGTH_BYTE = 16; + +type + TMD5CBits = array[0..7] of Byte; + +var + PADDING: TCnMD5Buffer = ( + $80, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00, + $00, $00, $00, $00, $00, $00, $00, $00 + ); + +function F(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and y) or ((not X) and z); +end; + +function G(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and z) or (y and (not z)); +end; + +function H(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor y xor z; +end; + +function I(X, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := y xor (X or (not z)); +end; + +procedure ROT(var X: Cardinal; N: BYTE); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + X := (X shl N) or (X shr (32 - N)); +end; + +procedure FF(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, F(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure GG(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, G(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure HH(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, H(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +procedure II(var A: Cardinal; B, C, D, X: Cardinal; S: BYTE; AC: Cardinal); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Inc(A, I(B, C, D) + X + AC); + ROT(A, S); + Inc(A, B); +end; + +// Encode Count bytes at Source into (Count / 4) DWORDs at Target +procedure Encode(Source, Target: Pointer; Count: Cardinal); +var + S: PByte; + T: PCardinal; + I: Cardinal; +begin + S := Source; + T := Target; + for I := 1 to Count div 4 do + begin + T^ := S^; + Inc(S); + T^ := T^ or (S^ shl 8); + Inc(S); + T^ := T^ or (S^ shl 16); + Inc(S); + T^ := T^ or (S^ shl 24); + Inc(S); + Inc(T); + end; +end; + +// Decode Count DWORDs at Source into (Count * 4) Bytes at Target +procedure Decode(Source, Target: Pointer; Count: Cardinal); +var + S: PCardinal; + T: PByte; + I: Cardinal; +begin + S := Source; + T := Target; + for I := 1 to Count do + begin + T^ := S^ and $ff; + Inc(T); + T^ := (S^ shr 8) and $ff; + Inc(T); + T^ := (S^ shr 16) and $ff; + Inc(T); + T^ := (S^ shr 24) and $ff; + Inc(T); + Inc(S); + end; +end; + +// Transform State according to first 64 bytes at Buffer +procedure Transform(Buffer: Pointer; var State: TCnMD5State); +var + A, B, C, D: Cardinal; + Block: TCnMD5Block; +begin + Encode(Buffer, @Block, 64); + A := State[0]; + B := State[1]; + C := State[2]; + D := State[3]; + FF (A, B, C, D, Block[ 0], 7, $d76aa478); + FF (D, A, B, C, Block[ 1], 12, $e8c7b756); + FF (C, D, A, B, Block[ 2], 17, $242070db); + FF (B, C, D, A, Block[ 3], 22, $c1bdceee); + FF (A, B, C, D, Block[ 4], 7, $f57c0faf); + FF (D, A, B, C, Block[ 5], 12, $4787c62a); + FF (C, D, A, B, Block[ 6], 17, $a8304613); + FF (B, C, D, A, Block[ 7], 22, $fd469501); + FF (A, B, C, D, Block[ 8], 7, $698098d8); + FF (D, A, B, C, Block[ 9], 12, $8b44f7af); + FF (C, D, A, B, Block[10], 17, $ffff5bb1); + FF (B, C, D, A, Block[11], 22, $895cd7be); + FF (A, B, C, D, Block[12], 7, $6b901122); + FF (D, A, B, C, Block[13], 12, $fd987193); + FF (C, D, A, B, Block[14], 17, $a679438e); + FF (B, C, D, A, Block[15], 22, $49b40821); + GG (A, B, C, D, Block[ 1], 5, $f61e2562); + GG (D, A, B, C, Block[ 6], 9, $c040b340); + GG (C, D, A, B, Block[11], 14, $265e5a51); + GG (B, C, D, A, Block[ 0], 20, $e9b6c7aa); + GG (A, B, C, D, Block[ 5], 5, $d62f105d); + GG (D, A, B, C, Block[10], 9, $2441453); + GG (C, D, A, B, Block[15], 14, $d8a1e681); + GG (B, C, D, A, Block[ 4], 20, $e7d3fbc8); + GG (A, B, C, D, Block[ 9], 5, $21e1cde6); + GG (D, A, B, C, Block[14], 9, $c33707d6); + GG (C, D, A, B, Block[ 3], 14, $f4d50d87); + GG (B, C, D, A, Block[ 8], 20, $455a14ed); + GG (A, B, C, D, Block[13], 5, $a9e3e905); + GG (D, A, B, C, Block[ 2], 9, $fcefa3f8); + GG (C, D, A, B, Block[ 7], 14, $676f02d9); + GG (B, C, D, A, Block[12], 20, $8d2a4c8a); + HH (A, B, C, D, Block[ 5], 4, $fffa3942); + HH (D, A, B, C, Block[ 8], 11, $8771f681); + HH (C, D, A, B, Block[11], 16, $6d9d6122); + HH (B, C, D, A, Block[14], 23, $fde5380c); + HH (A, B, C, D, Block[ 1], 4, $a4beea44); + HH (D, A, B, C, Block[ 4], 11, $4bdecfa9); + HH (C, D, A, B, Block[ 7], 16, $f6bb4b60); + HH (B, C, D, A, Block[10], 23, $bebfbc70); + HH (A, B, C, D, Block[13], 4, $289b7ec6); + HH (D, A, B, C, Block[ 0], 11, $eaa127fa); + HH (C, D, A, B, Block[ 3], 16, $d4ef3085); + HH (B, C, D, A, Block[ 6], 23, $4881d05); + HH (A, B, C, D, Block[ 9], 4, $d9d4d039); + HH (D, A, B, C, Block[12], 11, $e6db99e5); + HH (C, D, A, B, Block[15], 16, $1fa27cf8); + HH (B, C, D, A, Block[ 2], 23, $c4ac5665); + II (A, B, C, D, Block[ 0], 6, $f4292244); + II (D, A, B, C, Block[ 7], 10, $432aff97); + II (C, D, A, B, Block[14], 15, $ab9423a7); + II (B, C, D, A, Block[ 5], 21, $fc93a039); + II (A, B, C, D, Block[12], 6, $655b59c3); + II (D, A, B, C, Block[ 3], 10, $8f0ccc92); + II (C, D, A, B, Block[10], 15, $ffeff47d); + II (B, C, D, A, Block[ 1], 21, $85845dd1); + II (A, B, C, D, Block[ 8], 6, $6fa87e4f); + II (D, A, B, C, Block[15], 10, $fe2ce6e0); + II (C, D, A, B, Block[ 6], 15, $a3014314); + II (B, C, D, A, Block[13], 21, $4e0811a1); + II (A, B, C, D, Block[ 4], 6, $f7537e82); + II (D, A, B, C, Block[11], 10, $bd3af235); + II (C, D, A, B, Block[ 2], 15, $2ad7d2bb); + II (B, C, D, A, Block[ 9], 21, $eb86d391); + Inc(State[0], A); + Inc(State[1], B); + Inc(State[2], C); + Inc(State[3], D); +end; + +// Initialize given Context +procedure MD5Init(var Context: TCnMD5Context); +begin + with Context do + begin + State[0] := $67452301; + State[1] := $EFCDAB89; + State[2] := $98BADCFE; + State[3] := $10325476; + Count[0] := 0; + Count[1] := 0; + // ZeroMemory(@Buffer, SizeOf(TMD5Buffer)); + FillChar(Buffer, SizeOf(TCnMD5Buffer), 0); + end; +end; + +// Update given Context to include Length bytes of Input +procedure MD5Update(var Context: TCnMD5Context; Input: PAnsiChar; ByteLength: Cardinal); +var + Index: Cardinal; + PartLen: Cardinal; + I: Cardinal; +begin + with Context do + begin + Index := (Count[0] shr 3) and $3F; + Inc(Count[0], ByteLength shl 3); + if Count[0] < (ByteLength shl 3) then Inc(Count[1]); + Inc(Count[1], ByteLength shr 29); + end; + + PartLen := 64 - Index; + if ByteLength >= PartLen then + begin + Move(Input^, Context.Buffer[Index], PartLen); + Transform(@Context.Buffer, Context.State); + I := PartLen; + while I + 63 < ByteLength do + begin + Transform(@Input[I], Context.State); + Inc(I, 64); + end; + Index := 0; + end + else + I := 0; + + Move(Input[I], Context.Buffer[Index], ByteLength - I); +end; + +procedure MD5UpdateW(var Context: TCnMD5Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + MD5Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + MD5Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +// Finalize given Context, create Digest +procedure MD5Final(var Context: TCnMD5Context; var Digest: TCnMD5Digest); +var + Bits: TMD5CBits; + Index: Cardinal; + PadLen: Cardinal; +begin + Decode(@Context.Count, @Bits, 2); + Index := (Context.Count[0] shr 3) and $3f; + if Index < 56 then + PadLen := 56 - Index + else + PadLen := 120 - Index; + MD5Update(Context, @PADDING, PadLen); + MD5Update(Context, @Bits, 8); + Decode(@Context.State, @Digest, 4); +end; + +function InternalMD5Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnMD5Digest; CallBack: TCnMD5CalcProgressFunc = nil): Boolean; +var + Context: TCnMD5Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + if Size = 0 then + Exit; + + SavePos := Stream.Position; + TotalBytes := 0; + + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + MD5Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + MD5Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + MD5Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ݿ MD5 +function MD5(Input: PAnsiChar; ByteLength: Cardinal): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, Input, ByteLength); + MD5Final(Context, Result); +end; + +// ݿ MD5 +function MD5Buffer(const Buffer; Count: Cardinal): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(Buffer), Count); + MD5Final(Context, Result); +end; + +function MD5Bytes(Data: TBytes): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(@Data[0]), Length(Data)); + MD5Final(Context, Result); +end; + +// String ݽ MD5 +function MD5String(const Str: string): TCnMD5Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := MD5StringA(AStr); +end; + +// AnsiString ݽ MD5 +function MD5StringA(const Str: AnsiString): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(Str), Length(Str)); + MD5Final(Context, Result); +end; + +// WideString ݽ MD5 +function MD5StringW(const Str: WideString): TCnMD5Digest; +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5UpdateW(Context, PWideChar(Str), Length(Str)); + MD5Final(Context, Result); +end; + +// UnicodeString ݽֱӵ MD5 㣬ת +{$IFDEF UNICODE} +function MD5UnicodeString(const Str: string): TCnMD5Digest; +{$ELSE} +function MD5UnicodeString(const Str: WideString): TCnMD5Digest; +{$ENDIF} +var + Context: TCnMD5Context; +begin + MD5Init(Context); + MD5Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + MD5Final(Context, Result); +end; + +// ָļݽ MD5 +function MD5File(const FileName: string; + CallBack: TCnMD5CalcProgressFunc): TCnMD5Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnMD5Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + MD5Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + MD5Final(Context, Result); +{$ENDIF} + end; +end; + +// ָ MD5 +function MD5Stream(Stream: TStream; + CallBack: TCnMD5CalcProgressFunc = nil): TCnMD5Digest; +begin + InternalMD5Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +// ʮƸʽ MD5 Ӵֵ +function MD5Print(const Digest: TCnMD5Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnMD5Digest)); +end; + +// Ƚ MD5 ӴֵǷ +function MD5Match(const D1, D2: TCnMD5Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnMD5Digest)); +end; + +// MD5 Ӵֵת string +function MD5DigestToStr(const Digest: TCnMD5Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnMD5Digest)); +end; + +procedure MD5HmacInit(var Ctx: TCnMD5Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnMD5Digest; +begin + if KeyLength > HMAC_MD5_BLOCK_SIZE_BYTE then + begin + Sum := MD5Buffer(Key, KeyLength); + KeyLength := HMAC_MD5_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_MD5_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_MD5_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + MD5Init(Ctx); + MD5Update(Ctx, @(Ctx.Ipad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); +end; + +procedure MD5HmacUpdate(var Ctx: TCnMD5Context; Input: PAnsiChar; Length: Cardinal); +begin + MD5Update(Ctx, Input, Length); +end; + +procedure MD5HmacFinal(var Ctx: TCnMD5Context; var Output: TCnMD5Digest); +var + Len: Integer; + TmpBuf: TCnMD5Digest; +begin + Len := HMAC_MD5_OUTPUT_LENGTH_BYTE; + MD5Final(Ctx, TmpBuf); + MD5Init(Ctx); + MD5Update(Ctx, @(Ctx.Opad[0]), HMAC_MD5_BLOCK_SIZE_BYTE); + MD5Update(Ctx, @(TmpBuf[0]), Len); + MD5Final(Ctx, Output); +end; + +procedure MD5Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnMD5Digest); +var + Ctx: TCnMD5Context; +begin + MD5HmacInit(Ctx, Key, KeyByteLength); + MD5HmacUpdate(Ctx, Input, ByteLength); + MD5HmacFinal(Ctx, Output); +end; + +end. diff --git a/CnPack/Crypto/CnNative.dcu b/CnPack/Crypto/CnNative.dcu new file mode 100644 index 0000000000000000000000000000000000000000..6b75b118ea19893f0e12fe282c3f47c9989c3dbf GIT binary patch literal 48972 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 literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnNative.pas b/CnPack/Crypto/CnNative.pas new file mode 100644 index 0000000..972f9e4 --- /dev/null +++ b/CnPack/Crypto/CnNative.pas @@ -0,0 +1,4904 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnNative; +{* |
+================================================================================
+* ƣCnPack 
+* Ԫƣ32 λ 64 λƽ̨һЩͳһԼһʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪһ 32 λ 64 λƽ̨һЩͳһʵ֡
+*           Delphi XE 2 ֧ 32  64 ų NativeInt  NativeUInt 
+*           ǰ 32 λ 64 ̬仯Ӱ쵽 PointerReferenceȶ
+*           ǵԣ̶ȵ 32 λ Cardinal/Integer Ⱥ Pointer Щ
+*           ͨˣʹ 32 λҲֹ˱Ԫ˼ͣ
+*           ͬʱڵͰ汾͸߰汾 Delphi ʹá
+*
+*           ԪҲڲ֧ UInt64 ı Delphi 5/6/7  Int64 ģ UInt64
+*           ĸ㣬ӼȻ֧֣˳Ҫģ div  mod
+*           ַ Integer(APtr)  64 λ MacOS ׳ֽضϣҪ NativeInt
+*
+*           ʵ˴Сءֽת̶ʱȷĴײ㺯빤ࡣ
+*
+* ƽ̨PWin2000 + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6/7 XE 2
+*   õԪеַϱػʽ
+* ޸ļ¼2023.08.14 V2.4
+*               ϼʱ̶ĺ
+*           2022.11.11 V2.3
+*               ϼ޷ֽ˳
+*           2022.07.23 V2.2
+*               Ӽڴλ㺯תַΪ CnNative
+*           2022.06.08 V2.1
+*               ĸʱ̶ĽԼڴ浹ź
+*           2022.03.14 V2.0
+*               Ӽʮת
+*           2022.02.17 V1.9
+*                FPC ı֧
+*           2022.02.09 V1.8
+*               ڵĴСжϺ
+*           2021.09.05 V1.7
+*                Int64/UInt64 㺯
+*           2020.10.28 V1.6
+*                UInt64 صж㺯
+*           2020.09.06 V1.5
+*                UInt64 ƽĺ
+*           2020.07.01 V1.5
+*               ж 32 λ 64 λ޷Ƿĺ
+*           2020.06.20 V1.4
+*                32 λ 64 λȡ͵ 1 λλõĺ
+*           2020.01.01 V1.3
+*                32 λ޷͵ mul 㣬ڲ֧ UInt64 ϵͳ Int64 Ա
+*           2018.06.05 V1.2
+*                64 λ͵ div/mod 㣬ڲ֧ UInt64 ϵͳ Int64  
+*           2016.09.27 V1.1
+*                64 λ͵һЩ
+*           2011.07.06 V1.0
+*               Ԫʵֹ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, SysConst, Math {$IFDEF COMPILER5}, Windows {$ENDIF}; + // D5 Ҫ Windows е PByte +type + ECnNativeException = class(Exception); + {* Native 쳣} + +{$IFDEF COMPILER5} + PCardinal = ^Cardinal; + {* D5 System Ԫδ壬} + PByte = Windows.PByte; + {* D5 PByte Windows У汾 System У + ͳһһ¹ʹ PByte ʱ uses Windowsڿƽ̨} +{$ENDIF} + +{$IFDEF BCB5OR6} + PInt64 = ^Int64; + {* C++Builder 5/6 sysmac.h û PInt64 Ķ壨е PUINT64 Сдͬ㣩} +{$ENDIF} + +{$IFDEF SUPPORT_32_AND_64} + TCnNativeInt = NativeInt; + TCnNativeUInt = NativeUInt; + TCnNativePointer = NativeInt; + TCnNativeIntPtr = PNativeInt; + TCnNativeUIntPtr = PNativeUInt; +{$ELSE} + TCnNativeInt = Integer; + TCnNativeUInt = Cardinal; + TCnNativePointer = Integer; + TCnNativeIntPtr = PInteger; + TCnNativeUIntPtr = PCardinal; +{$ENDIF} + +{$IFDEF CPU64BITS} + TCnUInt64 = NativeUInt; + TCnInt64 = NativeInt; +{$ELSE} + {$IFDEF SUPPORT_UINT64} + TCnUInt64 = UInt64; + {$ELSE} + TCnUInt64 = packed record // ֻĽṹ + case Boolean of + True: (Value: Int64); + False: (Lo32, Hi32: Cardinal); + end; + {$ENDIF} + TCnInt64 = Int64; +{$ENDIF} + +// TUInt64 cnvcl в֧ UInt64 div mod +{$IFDEF SUPPORT_UINT64} + TUInt64 = UInt64; + {$IFNDEF SUPPORT_PUINT64} + PUInt64 = ^UInt64; + {$ENDIF} +{$ELSE} + TUInt64 = Int64; + PUInt64 = ^TUInt64; +{$ENDIF} + +{$IFNDEF SUPPORT_INT64ARRAY} + // ϵͳûж Int64Array + Int64Array = array[0..$0FFFFFFE] of Int64; + PInt64Array = ^Int64Array; +{$ENDIF} + + TUInt64Array = array of TUInt64; // ̬ƺ׺;̬гͻ + + ExtendedArray = array[0..65537] of Extended; + PExtendedArray = ^ExtendedArray; + + PCnWord16Array = ^TCnWord16Array; + TCnWord16Array = array [0..0] of Word; + +{$IFDEF POSIX64} + TCnLongWord32 = Cardinal; // Linux64/MacOS64 (or POSIX64?) LongWord is 64 Bits +{$ELSE} + TCnLongWord32 = LongWord; +{$ENDIF} + PCnLongWord32 = ^TCnLongWord32; + + TCnLongWord32Array = array [0..MaxInt div SizeOf(Integer) - 1] of TCnLongWord32; + + PCnLongWord32Array = ^TCnLongWord32Array; + +{$IFNDEF TBYTES_DEFINED} + TBytes = array of Byte; + {* ޷ֽڶ̬飬δʱ} +{$ENDIF} + + TShortInts = array of ShortInt; + {* зֽڶ̬} + + TSmallInts = array of SmallInt; + {* з˫ֽڶ̬} + + TWords = array of Word; + {* ޷˫ֽڶ̬} + + TIntegers = array of Integer; + {* зֽڶ̬} + + TCardinals = array of Cardinal; + {* ޷ֽڶ̬} + + PCnByte = ^Byte; + PCnWord = ^Word; + + TCnBitOperation = (boAnd, boOr, boXor, boNot); + {* λ} + +type + TCnMemSortCompareProc = function (P1, P2: Pointer; ElementByteSize: Integer): Integer; + {* ڴ̶ߴȽϺԭ} + +const + CN_MAX_SQRT_INT64: Cardinal = 3037000499; + CN_MAX_INT8: ShortInt = $7F; + CN_MIN_INT8: ShortInt = -128; + CN_MAX_INT16: SmallInt = $7FFF; + CN_MIN_INT16: SmallInt = -32768; + CN_MAX_INT32: Integer = $7FFFFFFF; + CN_MIN_INT32: Integer = $80000000; // 뾯棬 -2147483648 + CN_MIN_INT32_IN_INT64: Int64 = $0000000080000000; + CN_MAX_INT64: Int64 = $7FFFFFFFFFFFFFFF; + CN_MIN_INT64: Int64 = $8000000000000000; + CN_MAX_UINT8: Byte = $FF; + CN_MAX_UINT16: Word = $FFFF; + CN_MAX_UINT32: Cardinal = $FFFFFFFF; + CN_MAX_TUINT64: TUInt64 = $FFFFFFFFFFFFFFFF; + CN_MAX_SIGNED_INT64_IN_TUINT64: TUInt64 = $7FFFFFFFFFFFFFFF; + +{* + D567 Ȳ֧ UInt64 ıȻ Int64 UInt64 мӼ洢 + ˳޷ֱɣװ System е _lludiv _llumod + ʵ Int64 ʾ UInt64 ݵ div mod ܡ +} +function UInt64Mod(A: TUInt64; B: TUInt64): TUInt64; +{* 64 λ޷ࡣ + + + A: TUInt64 - + B: TUInt64 - + + ֵTUInt64 - +} + +function UInt64Div(A: TUInt64; B: TUInt64): TUInt64; +{* 64 λ޷ + + + A: TUInt64 - + B: TUInt64 - + + ֵTUInt64 - +} + +function UInt64Mul(A: Cardinal; B: Cardinal): TUInt64; +{* 32 λ޷ˡڲ֧ UInt64 ƽ̨ϣ UInt64 ʽ Int64  + ֱʹ Int64 п + + + A: Cardinal - һ + B: Cardinal - + + ֵTUInt64 - +} + +procedure UInt64AddUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); +{* 64 λ޷ӣ ResLo ResHi С + עڲʵְ㷨ΪӣʵResHi Ȼ 1ֱж 1 + + + A: TUInt64 - һ + B: TUInt64 - + var ResLo: TUInt64 - ͵λ + var ResHi: TUInt64 - ͸λ + + ֵޣ +} + +procedure UInt64MulUInt64(A: TUInt64; B: TUInt64; var ResLo: TUInt64; var ResHi: TUInt64); +{* 64 λ޷ˣ ResLo ResHi СWin 64 λûʵ֣Լһϡ + + + A: TUInt64 - һ + B: TUInt64 - + var ResLo: TUInt64 - λ + var ResHi: TUInt64 - λ + + ֵޣ +} + +function UInt64ToHex(N: TUInt64): string; +{* 64 λ޷תΪʮַ + + + N: TUInt64 - תֵ + + ֵstring - ʮַ +} + +function UInt64ToStr(N: TUInt64): string; +{* 64 λ޷תΪʮַ + + + N: TUInt64 - תֵ + + ֵstring - ʮַ +} + +function StrToUInt64(const S: string): TUInt64; +{* ַתΪ 64 λ޷ + + + const S: string - תַ + + ֵTUInt64 - ת +} + +function UInt64Compare(A: TUInt64; B: TUInt64): Integer; +{* Ƚ 64 λ޷ֱֵݱȽϵĽǴڡڻС 10-1 + + + A: TUInt64 - Ƚϵһ + B: TUInt64 - Ƚϵ + + ֵInteger - رȽϽ +} + +function UInt64Sqrt(N: TUInt64): TUInt64; +{* 64 λ޷ƽ֡ + + + N: TUInt64 - ƽ + + ֵTUInt64 - ƽ +} + +function UInt32IsNegative(N: Cardinal): Boolean; +{* ж 32 λ޷ 32 λзʱǷС 0 + + + N: Cardinal - жϵֵ + + ֵBoolean - ǷС 0 +} + +function UInt64IsNegative(N: TUInt64): Boolean; +{* ж 64 λ޷ 64 λзʱǷС 0 + + + N: TUInt64 - жϵֵ + + ֵBoolean - ǷС 0 +} + +procedure UInt64SetBit(var B: TUInt64; Index: Integer); +{* 64 λijһλ 1λ Index 0 ʼ 63 + + + var B: TUInt64 - λֵ + Index: Integer - 1 λ + + ֵޣ +} + +procedure UInt64ClearBit(var B: TUInt64; Index: Integer); +{* 64 λijһλ 0λ Index 0 ʼ 63 + + + var B: TUInt64 - λֵ + Index: Integer - 0 λ + + ֵޣ +} + +function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; +{* 64 λijһλǷ 1λ Index 0 ʼ 63 + + + B: TUInt64 - жϵֵ + Index: Integer - жϵλ + + ֵBoolean - ظλǷ 1 +} + +function GetUInt64HighBits(B: TUInt64): Integer; +{* 64 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: TUInt64 - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt32HighBits(B: Cardinal): Integer; +{* 32 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Cardinal - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt16HighBits(B: Word): Integer; +{* 16 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Word - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt8HighBits(B: Byte): Integer; +{* 8 λ 1 ߶λǵڼλλ 0û 1 -1 + + + B: Byte - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt64LowBits(B: TUInt64): Integer; +{* 64 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: TUInt64 - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt32LowBits(B: Cardinal): Integer; +{* 32 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Cardinal - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt16LowBits(B: Word): Integer; +{* 16 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Word - жϵֵ + + ֵInteger - 1 λ +} + +function GetUInt8LowBits(B: Byte): Integer; +{* 8 λ 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 + + + B: Byte - жϵֵ + + ֵInteger - 1 λ +} + +function Int64Mod(M: Int64; N: Int64): Int64; +{* װ Int64 ModM ֵʱȡģģ N Ҫס + + + M: Int64 - + N: Int64 - + + ֵInt64 - +} + +function IsUInt32PowerOf2(N: Cardinal): Boolean; +{* жһ 32 λ޷Ƿ 2 ݡ + + + N: Cardinal - жϵֵ + + ֵBoolean - Ƿ 2 +} + +function IsUInt64PowerOf2(N: TUInt64): Boolean; +{* жһ 64 λ޷Ƿ 2 ݡ + + + N: TUInt64 - жϵֵ + + ֵBoolean - Ƿ 2 +} + +function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; +{* õһָ 32 λ޷ȵ 2 ݣ򷵻 0 + + + N: Cardinal - ֵ + + ֵCardinal - ط 2 ݻ 0 +} + +function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; +{* õһָ 64 λ޷ȵ 2 ݣ򷵻 0 + + + N: TUInt64 - ֵ + + ֵTUInt64 - ط 2 ݻ 0 +} + +function IsInt32AddOverflow(A: Integer; B: Integer): Boolean; +{* ж 32 λзǷ 32 λзޡ + + + A: Integer - һ + B: Integer - + + ֵBoolean - Ƿ +} + +function IsUInt32AddOverflow(A: Cardinal; B: Cardinal): Boolean; +{* ж 32 λ޷Ƿ 32 λ޷ޡ + + + A: Cardinal - һ + B: Cardinal - + + ֵBoolean - Ƿ +} + +function IsInt64AddOverflow(A: Int64; B: Int64): Boolean; +{* ж 64 λзǷ 64 λзޡ + + + A: Int64 - һ + B: Int64 - + + ֵBoolean - Ƿ +} + +function IsUInt64AddOverflow(A: TUInt64; B: TUInt64): Boolean; +{* ж 64 λ޷Ƿ 64 λ޷ޡ + + + A: TUInt64 - һ + B: TUInt64 - + + ֵBoolean - Ƿ +} + +function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; +{* жһ 64 λ޷ȥһ 64 λ޷ĽǷ񳬳 32 λзΧ + 64 λе JMP תжϡ + + + A: TUInt64 - + B: TUInt64 - + + ֵBoolean - Ƿ񳬳 32 λзΧ +} + +procedure UInt64Add(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); +{* 64 λ޷ӣA + B => R 1 ýλλ㡣 + + + var R: TUInt64 - + A: TUInt64 - һ + B: TUInt64 - + out Carry: Integer - λ + + ֵޣ +} + +procedure UInt64Sub(var R: TUInt64; A: TUInt64; B: TUInt64; out Carry: Integer); +{* 64 λ޷A - B => Rнλ 1 ýλλ㡣 + + + var R: TUInt64 - + A: TUInt64 - + B: TUInt64 - + out Carry: Integer - λ + + ֵޣ +} + +function IsInt32MulOverflow(A: Integer; B: Integer): Boolean; +{* ж 32 λзǷ 32 λзޡ + + + A: Integer - һ + B: Integer - + + ֵBoolean - Ƿ +} + +function IsUInt32MulOverflow(A: Cardinal; B: Cardinal): Boolean; +{* ж 32 λ޷Ƿ 32 λ޷ + + + A: Cardinal - һ + B: Cardinal - + + ֵBoolean - Ƿ +} + +function IsUInt32MulOverflowInt64(A: Cardinal; B: Cardinal; out R: TUInt64): Boolean; +{* ж 32 λ޷Ƿ 64 λзޣδҲ False ʱR ֱӷؽ + Ҳ TrueҪµ UInt64Mul ʵʩˡ + + + A: Cardinal - һ + B: Cardinal - + out R: TUInt64 - δʱػ + + ֵBoolean - Ƿ +} + +function IsInt64MulOverflow(A: Int64; B: Int64): Boolean; +{* ж 64 λзǷ 64 λзޡ + + + A: Int64 - һ + B: Int64 - + + ֵBoolean - Ƿ +} + +function PointerToInteger(P: Pointer): Integer; +{* ָת֧ͣ 32/64 λע 64 λ¿ܻᶪ 32 λݡ + + + P: Pointer - תָ + + ֵInteger - ת +} + +function IntegerToPointer(I: Integer): Pointer; +{* תָ֧ͣ 32/64 λ + + + I: Integer - ת + + ֵPointer - תָ +} + +function Int64NonNegativeAddMod(A: Int64; B: Int64; N: Int64): Int64; +{* 64 λзΧĺ࣬Ҫ N 0 + + + A: Int64 - һ + B: Int64 - һ + N: Int64 - ģ + + ֵInt64 - Ľ +} + +function UInt64NonNegativeAddMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; +{* 64 λ޷Χĺ࣬Ҫ N 0 + + + A: TUInt64 - һ + B: TUInt64 - + N: TUInt64 - ģ + + ֵTUInt64 - Ľ +} + +function Int64NonNegativeMulMod(A: Int64; B: Int64; N: Int64): Int64; +{* 64 λзΧڵֱ࣬Ӽ㣬Ҫ N 0 + + + A: Int64 - һ + B: Int64 - + N: Int64 - ģ + + ֵInt64 - Ľ +} + +function UInt64NonNegativeMulMod(A: TUInt64; B: TUInt64; N: TUInt64): TUInt64; +{* 64 λ޷Χڵֱ࣬Ӽ㣬 + + + A: TUInt64 - һ + B: TUInt64 - + N: TUInt64 - ģ + + ֵTUInt64 - Ľ +} + +function Int64NonNegativeMod(N: Int64; P: Int64): Int64; +{* װ 64 λзķǸຯҲΪʱӸ豣֤ P 0 + + + N: Int64 - + P: Int64 - + + ֵInt64 - طǸĽ +} + +function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; +{* 64 λзķǸָݣ + + + N: Int64 - + Exp: Integer - ָҪ 0 + + ֵInt64 - ݵĽ +} + +function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; +{* 64 λзķǸη֣ + + + N: Int64 - + Exp: Integer - + + ֵInt64 - ؿֽ +} + +function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; +{* 64 λ޷ķǸָݣ + + + N: TUInt64 - + Exp: Integer - ָҪ 0 + + ֵTUInt64 - ݵĽ +} + +function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; +{* 64 λ޷ķǸη֣ + + + N: TUInt64 - + Exp: Integer - + + ֵTUInt64 - ؿֽ +} + +function CurrentByteOrderIsBigEndian: Boolean; +{* صǰڻǷǴˣҲǷеĸֽڴ洢ڽϵ͵ʼַ + ϴҵĶϰߣ粿ָ ARM MIPS + + + ޣ + + ֵBoolean - صǰڻǷǴ +} + +function CurrentByteOrderIsLittleEndian: Boolean; +{* صǰڻǷСˣҲǷеĸֽڴ洢ڽϸߵʼַ x86 벿Ĭ ARM + + + ޣ + + ֵBoolean - صǰڻǷС +} + +function Int64ToBigEndian(Value: Int64): Int64; +{* ȷ 64 λзֵΪˣС˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - شֵ +} + +function Int32ToBigEndian(Value: Integer): Integer; +{* ȷ 32 λзֵΪˣС˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - شֵ +} + +function Int16ToBigEndian(Value: SmallInt): SmallInt; +{* ȷ 16 λзֵΪˣС˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - شֵ +} + +function Int64ToLittleEndian(Value: Int64): Int64; +{* ȷ 64 λзֵΪСˣڴ˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - شֵ +} + +function Int32ToLittleEndian(Value: Integer): Integer; +{* ȷ 32 λзֵΪСˣڴ˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - Сֵ +} + +function Int16ToLittleEndian(Value: SmallInt): SmallInt; +{* ȷ 16 λзֵΪСˣڴ˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - Сֵ +} + +function UInt64ToBigEndian(Value: TUInt64): TUInt64; +{* ȷ 64 λ޷ֵΪˣС˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - شֵ +} + +function UInt32ToBigEndian(Value: Cardinal): Cardinal; +{* ȷ 32 λ޷ֵΪˣС˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - شֵ +} + +function UInt16ToBigEndian(Value: Word): Word; +{* ȷ 16 λ޷ֵΪˣС˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - شֵ +} + +function UInt64ToLittleEndian(Value: TUInt64): TUInt64; +{* ȷ 64 λ޷ֵΪСˣڴ˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - شֵ +} + +function UInt32ToLittleEndian(Value: Cardinal): Cardinal; +{* ȷ 32 λ޷ֵΪСˣڴ˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - Сֵ +} + +function UInt16ToLittleEndian(Value: Word): Word; +{* ȷ 16 λ޷ֵΪСˣڴ˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - Сֵ +} + +function Int64HostToNetwork(Value: Int64): Int64; +{* 64 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - ֽ˳ֵ +} + +function Int32HostToNetwork(Value: Integer): Integer; +{* 32 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - ֽ˳ֵ +} + +function Int16HostToNetwork(Value: SmallInt): SmallInt; +{* 16 λзֵֽ˳תΪֽ˳С˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - ֽ˳ֵ +} + +function Int64NetworkToHost(Value: Int64): Int64; +{* 64 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Int64 - ת 64 λз + + ֵInt64 - ֽ˳ֵ +} + +function Int32NetworkToHost(Value: Integer): Integer; +{* 32 λзֵֽ˳תΪֽ˳С˻лת + + + Value: Integer - ת 32 λз + + ֵInteger - ֽ˳ֵ +} + +function Int16NetworkToHost(Value: SmallInt): SmallInt; +{* 16 λзֵֽ˳תΪֽ˳С˻лת + + + Value: SmallInt - ת 16 λз + + ֵSmallInt - ֽ˳ֵ +} + +function UInt64HostToNetwork(Value: TUInt64): TUInt64; +{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - ֽ˳ֵ +} + +function UInt32HostToNetwork(Value: Cardinal): Cardinal; +{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - ֽ˳ֵ +} + +function UInt16HostToNetwork(Value: Word): Word; +{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - ֽ˳ֵ +} + +function UInt64NetworkToHost(Value: TUInt64): TUInt64; +{* 64 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: TUInt64 - ת 64 λ޷ + + ֵTUInt64 - ֽ˳ֵ +} + +function UInt32NetworkToHost(Value: Cardinal): Cardinal; +{* 32 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Cardinal - ת 32 λ޷ + + ֵCardinal - ֽ˳ֵ +} + +function UInt16NetworkToHost(Value: Word): Word; +{* 16 λ޷ֵֽ˳תΪֽ˳С˻лת + + + Value: Word - ת 16 λ޷ + + ֵWord - ֽ˳ֵ +} + +procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); +{* һƬڴֽ˳תΪֽ˳С˻лת + ÷ӦóϽ٣¶ġֽתѾ㹻 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵޣ +} + +procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); +{* һƬڴֽ˳תΪֽ˳С˻лת + ÷ӦóϽ٣¶ġֽתѾ㹻 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵޣ +} + +procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); +{* ֽ˳һڴ飬ֽڲ䡣 + + + Mem: Pointer - õݿַ + MemByteLen: Integer - õݿֽڳ + + ֵޣ +} + +function ReverseBitsInInt8(V: Byte): Byte; +{* һֽڲλݡ + + + V: Byte - õһֽ + + ֵByte - صֵ +} + +function ReverseBitsInInt16(V: Word): Word; +{* öֽڼڲλݡ + + + V: Word - õĶֽ + + ֵWord - صֵ +} + +function ReverseBitsInInt32(V: Cardinal): Cardinal; +{* ֽڼڲλݡ + + + V: Cardinal - õֽ + + ֵCardinal - صֵ +} + +function ReverseBitsInInt64(V: Int64): Int64; +{* ðֽڼڲλݡ + + + V: Int64 - õİֽ + + ֵInt64 - صֵ +} + +procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); +{* ֽ˳һڴ飬ÿֽҲ + + + Mem: Pointer - õݿַ + MemByteLen: Integer - õݿֽڳ + + ֵޣ +} + +procedure MemoryAnd(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ룬 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryOr(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryXor(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* 鳤ͬڴ AMem BMem λ򣬽 ResMem У߿ͬ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); +{* һڴ AMem ȡ ResMem У߿ͬ + + + Mem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + ResMem: Pointer - ݿַ + + ֵޣ +} + +procedure MemoryShiftLeft(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + BitCount: Integer - Ƶλ + + ֵޣ +} + +procedure MemoryShiftRight(AMem: Pointer; BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +{* AMem ڴ BitCount λ BMemڴַλƣλ 0߿ȡ + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + BitCount: Integer - Ƶλ + + ֵޣ +} + +function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; +{* ڴij Bit λǷ 1ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵBoolean - Ƿ 1 +} + +procedure MemorySetBit(Mem: Pointer; N: Integer); +{* ڴij Bit λ 1ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵޣ +} + +procedure MemoryClearBit(Mem: Pointer; N: Integer); +{* ڴij Bit λ 0ڴַλ 0ֽڻұΪ 0 + + + Mem: Pointer - ݿַ + N: Integer - λ + + ֵޣ +} + +function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean = False): string; +{* һڴݴӵ͵ֽ˳ΪַSep ʾֽ֮Ƿոָ + + + Mem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + Sep: Boolean - ֽ֮Ƿÿոָ + + ֵstring - ضַ +} + +procedure MemorySwap(AMem: Pointer; BMem: Pointer; MemByteLen: Integer); +{* ͬȵڴݣͬڴʲô + + + AMem: Pointer - ݿַһ + BMem: Pointer - ݿַ + MemByteLen: Integer - ݿֽڳ + + ֵޣ +} + +function MemoryCompare(AMem: Pointer; BMem: Pointer; MemByteLen: Integer): Integer; +{* ޷ķʽȽڴ棬 10-1ͬڴֱӷ 0 + + + AMem: Pointer - Ƚϵݿַһ + BMem: Pointer - Ƚϵݿַ + MemByteLen: Integer - Ƚϵݿֽڳ + + ֵInteger - رȽϵĽ +} + +procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; + ElementCount: Integer; CompareProc: TCnMemSortCompareProc = nil); +{* Թ̶СԪص + + + Mem: Pointer - ݿַ + ElementByteSize: Integer - Ԫֽڳ + ElementCount: Integer - ݿԪصĸ + CompareProc: TCnMemSortCompareProc - ԪرȽϵĻص + + ֵޣ +} + +function UInt8ToBinStr(V: Byte): string; +{* һ 8 λ޷תΪַ + + + V: Byte - ת 8 λ޷ + + ֵstring - ضַ +} + +function UInt16ToBinStr(V: Word): string; +{* һ 16 λ޷תΪַ + + + V: Word - ת 16 λ޷ + + ֵstring - ضַ +} + +function UInt32ToBinStr(V: Cardinal): string; +{* һ 32 λ޷תΪַ + + + V: Cardinal - ת 32 λ޷ + + ֵstring - ضַ +} + +function UInt32ToStr(V: Cardinal): string; +{* һ 32 λ޷תΪʮַ + + + V: Cardinal - ת 32 λ޷ + + ֵstring - ʮַ +} + +function UInt64ToBinStr(V: TUInt64): string; +{* һ 64 λ޷תΪַ + + + V: TUInt64 - ת 64 λ޷ + + ֵstring - ضַ +} + +function HexToInt(const Hex: string): Integer; overload; +{* һʮַתΪͣʺϽ϶ 2 ַַ + + + const Hex: string - תʮַ + + ֵInteger - +} + +function HexToInt(Hex: PChar; CharLen: Integer): Integer; overload; +{* һʮַָָתΪͣʺϽ϶ 2 ַַ + + + Hex: PChar - תʮַַ + CharLen: Integer - ַ + + ֵInteger - +} + +function IsHexString(const Hex: string): Boolean; +{* жһַǷϷʮִַСд + + + const Hex: string - жϵʮַ + + ֵBoolean - ǷǺϷʮַ +} + +function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; +{* ڴתΪʮַڴλݳַ󷽣൱ֽ˳ + UseUpperCase ݵĴСд + + + InData: Pointer - תݿַ + ByteLength: Integer - תݿֽڳ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToData(const Hex: string; OutData: Pointer = nil): Integer; +{* ʮַתΪڴ飬ַ󷽵ݳڴλ൱ֽ˳ + ʮַΪתʧʱ׳쳣תɹֽ + ע OutData Ӧָ㹻תݵֽڳΪ Length(Hex) div 2 + nilֻֽڳȣʽת + + + const Hex: string - תʮַ + OutData: Pointer - ֽڳӦΪ Length(Hex) div 2 + + ֵInteger - תֽڳ +} + +function StringToHex(const Data: string; UseUpperCase: Boolean = True): string; +{* ַתΪʮַUseUpperCase ݵĴСд + + + const Data: string - תַ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - תʮַ +} + +function HexToString(const Hex: string): string; +{* ʮַתΪַʮַΪתʧʱ׳쳣 + + + const Hex: string - תʮַ + + ֵstring - תַ +} + +function HexToAnsiStr(const Hex: AnsiString): AnsiString; +{* ʮַתΪַʮַΪתʧʱ׳쳣 + + + const Hex: AnsiString - תʮַ + + ֵAnsiString - תַ +} + +function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean = True): AnsiString; +{* AnsiString תΪʮַUseUpperCase ݵĴСд + + + const Data: AnsiString - תַ + UseUpperCase: Boolean - ʮַڲǷд + + ֵAnsiString - ʮַ +} + +function BytesToHex(Data: TBytes; UseUpperCase: Boolean = True): string; +{* ֽתΪʮַ±λݳַ󷽣൱ֽ˳ + UseUpperCase ݵĴСд + + + Data: TBytes - תֽ + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToBytes(const Hex: string): TBytes; +{* ʮַתΪֽ飬ַߵݳ±λ൱ֽ˳ + ַΪתʧʱ׳쳣 + + + const Hex: string - תʮַ + + ֵTBytes - ½ֽ +} + +function StreamToHex(Stream: TStream; UseUpperCase: Boolean = True): string; +{* еȫݴͷתΪʮַ + + + Stream: TStream - + UseUpperCase: Boolean - ʮַڲǷд + + ֵstring - ʮַ +} + +function HexToStream(const Hex: string; Stream: TStream): Integer; +{* ʮַתдУдֽ + + + const Hex: string - תʮַ + Stream: TStream - д + + ֵInteger - дֽ +} + +procedure ReverseBytes(Data: TBytes); +{* ֽ˳һֽ顣 + + + Data: TBytes - õֽ + + ֵޣ +} + +function CloneBytes(Data: TBytes): TBytes; +{* һµֽ + + + Data: TBytes - Ƶֽ + + ֵTBytes - ½ֽ +} + +function StreamToBytes(Stream: TStream): TBytes; +{* ͷȫֽ飬½ֽ顣 + + + Stream: TStream - + + ֵTBytes - ½ֽ +} + +function BytesToStream(Data: TBytes; OutStream: TStream): Integer; +{* ֽдԭʼдֽ + + + Data: TBytes - дֽ + OutStream: TStream - д + + ֵInteger - дֽ +} + +function AnsiToBytes(const Str: AnsiString): TBytes; +{* AnsiString ֱתΪֽ飬롣 + + + const Str: AnsiString - תַ + + ֵTBytes - תֽ +} + +function BytesToAnsi(Data: TBytes): AnsiString; +{* ֱֽתΪ AnsiString롣 + + + Data: TBytes - תֽ + + ֵAnsiString - תַ +} + +function BytesToString(Data: TBytes): string; +{* ֽתΪ stringڲ Byte ֵΪ Char롣 + + + Data: TBytes - תֽ + + ֵstring - תַ +} + +function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; +{* ڴתΪ stringڲֽڸֵ롣 + + + Mem: Pointer - תݿַ + MemByteLen: Integer - תݿֽڳ + + ֵstring - תַ +} + +function BitsToString(Bits: TBits): string; +{* λתΪ 0 1 ַ + + + Bits: TBits - תλ + + ֵstring - תַ +} + +function ConcatBytes(A: TBytes; B: TBytes): TBytes; +{* A B ֽ˳ƴ÷һֽ飬A B ֲ䡣 + + + A: TBytes - ƴӵֽһ + B: TBytes - ƴӵֽ + + ֵTBytes - ƴӵֽ +} + +function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; +{* ½һֽ飬һƬڴݹ + + + Data: Pointer - ݿַ + DataByteLen: Integer - ݿֽڳ + + ֵTBytes - ½ֽ +} + +function CompareBytes(A: TBytes; B: TBytes): Boolean; overload; +{* ȽֽǷͬ + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + + ֵBoolean - رȽϽǷͬ +} + +function CompareBytes(A: TBytes; B: TBytes; MaxLength: Integer): Boolean; overload; +{* Ƚֽǰ MaxLength ֽڵǷͬ + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + MaxLength: Integer - Ƚϵֽ + + ֵBoolean - رȽϽǷͬ +} + +function MoveMost(const Source; var Dest; ByteLen: Integer; MostLen: Integer): Integer; +{* Source ƶ ByteLen Ҳ MostLen ֽڵ Dest Уʵƶֽ + ByteLen С MostLen Dest 0Ҫ Dest MostLen + + + const Source - ƶԴλáַ + var Dest - ƶĿλáַҪ MostLen ֽ + ByteLen: Integer - ƶֽ + MostLen: Integer - ƶֽ + + ֵInteger - ʵƶֽ +} + +// =============================== =================================== + +function SarInt8(var V: Byte; ShiftCount: Integer): Byte; +{* һ 8 λƣҲDZλơ + + + var V: Byte - Ƶ 8 λ + ShiftCount: Integer - Ƶλ + + ֵByte - λֵ +} + +function SarInt16(var V: Word; ShiftCount: Integer): Word; +{* һ 16 λƣҲDZλơ + + + var V: Word - Ƶ 16 λ + ShiftCount: Integer - Ƶλ + + ֵWord - λֵ +} + +function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; +{* һ 32 λƣҲDZλơ + + + var V: Cardinal - Ƶ 32 λ + ShiftCount: Integer - Ƶλ + + ֵCardinal - λֵ +} + +function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; +{* һ 64 λƣҲDZλơ + + + var V: TUInt64 - Ƶ 64 λ + ShiftCount: Integer - Ƶλ + + ֵTUInt64 - λֵ +} + +// ================ ִʱ̶ if жϵIJ߼ =============== + +procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A: Byte; var B: Byte); +{* 8 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Byte - 8 λͱһ + var B: Byte - 8 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A: Word; var B: Word); +{* 16 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Word - 16 λͱһ + var B: Word - 16 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A: Cardinal; var B: Cardinal); +{* 32 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: Cardinal - 32 λͱһ + var B: Cardinal - 32 λͱ + + ֵޣ +} + +procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A: TUInt64; var B: TUInt64); +{* 64 λͱִʱ̶CanSwap Ϊ True ʱʵʩ A B + + + CanSwap: Boolean - Ƿ񽻻 + var A: TUInt64 - 64 λͱһ + var B: TUInt64 - 64 λͱ + + ֵޣ +} + +function ConstTimeEqual8(A: Byte; B: Byte): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Byte - Ƚϵ 8 λͱһ + B: Byte - Ƚϵ 8 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual16(A: Word; B: Word): Boolean; +{* ˫ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Word - Ƚϵ 16 λͱһ + B: Word - Ƚϵ 16 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual32(A: Cardinal; B: Cardinal): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: Cardinal - Ƚϵ 32 λͱһ + B: Cardinal - Ƚϵ 32 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeEqual64(A: TUInt64; B: TUInt64): Boolean; +{* ֽڵִʱ̶ıȽϣ CPU ָתԤ⵼µִʱ죬ͬʱ True + + + A: TUInt64 - Ƚϵ 64 λͱһ + B: TUInt64 - Ƚϵ 64 λͱ + + ֵBoolean - Ƿ +} + +function ConstTimeBytesEqual(A: TBytes; B: TBytes): Boolean; +{* ͬȵִֽʱ̶ıȽϣͬʱ True + + + A: TBytes - Ƚϵֽһ + B: TBytes - Ƚϵֽ + + ֵBoolean - Ƿ +} + +function ConstTimeExpandBoolean8(V: Boolean): Byte; +{* V ֵ 8 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵByte - $FF 0 +} + +function ConstTimeExpandBoolean16(V: Boolean): Word; +{* V ֵ 16 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵWord - $FFFF 0 +} + +function ConstTimeExpandBoolean32(V: Boolean): Cardinal; +{* V ֵ 32 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵCardinal - $FFFFFFFF 0 +} + +function ConstTimeExpandBoolean64(V: Boolean): TUInt64; +{* V ֵ 64 λȫ 1 ȫ 0 + + + V: Boolean - Ƿ񷵻ȫ 1 + + ֵTUInt64 - $FFFFFFFFFFFFFFFF 0 +} + +function ConstTimeConditionalSelect8(Condition: Boolean; A: Byte; B: Byte): Byte; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Byte - ѡ 8 λһ + B: Byte - ѡ 8 λ + + ֵByte - ѡ 8 λ +} + +function ConstTimeConditionalSelect16(Condition: Boolean; A: Word; B: Word): Word; +{* ˫ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Word - ѡ 16 λһ + B: Word - ѡ 16 λ + + ֵWord - ѡ 16 λ +} + +function ConstTimeConditionalSelect32(Condition: Boolean; A: Cardinal; B: Cardinal): Cardinal; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: Cardinal - ѡ 32 λһ + B: Cardinal - ѡ 32 λ + + ֵCardinal - ѡ 32 λ +} + +function ConstTimeConditionalSelect64(Condition: Boolean; A: TUInt64; B: TUInt64): TUInt64; +{* ֽڱִʱ̶жѡCondtion Ϊ True ʱ A򷵻 B + + + Condition: Boolean - Ƿѡ A ҲDzһ + A: TUInt64 - ѡ 64 λһ + B: TUInt64 - ѡ 64 λ + + ֵTUInt64 - ѡ 64 λ +} + +// ================ ִʱ̶ if жϵIJ߼ =============== + +{$IFDEF MSWINDOWS} + +// ĸΪ Intel ֻ֧࣬ 32 λ 64 λ Intel CPUӦCPUX86 CPUX64 + +procedure Int64DivInt32Mod(A: Int64; B: Integer; + var DivRes: Integer; var ModRes: Integer); +{* 64 λз 32 λз̷ DivRes ModRes + б֤ 32 λΧڣ쳣 + + + A: Int64 - + B: Integer - + var DivRes: Integer - + var ModRes: Integer - + + ֵޣ +} + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; + var DivRes: Cardinal; var ModRes: Cardinal); +{* 64 λ޷ 32 λ޷̷ DivRes ModRes + б֤ 32 λΧڣ쳣 + + + A: TUInt64 - + B: Cardinal - + var DivRes: Cardinal - + var ModRes: Cardinal - + + ֵޣ +} + +procedure Int128DivInt64Mod(ALo: Int64; AHi: Int64; B: Int64; + var DivRes: Int64; var ModRes: Int64); +{* 128 λз 64 λз̷ DivRes ModRes + б֤ 64 λΧڣ쳣 + + + ALo: Int64 - 64 λ + AHi: Int64 - 64 λ + B: Int64 - + var DivRes: Int64 - + var ModRes: Int64 - + + ֵޣ +} + +procedure UInt128DivUInt64Mod(ALo: TUInt64; AHi: TUInt64; B: TUInt64; + var DivRes: TUInt64; var ModRes: TUInt64); +{* 128 λ޷ 64 λ޷̷ DivRes ModRes + б֤ 64 λΧڣ쳣 + + + ALo: TUInt64 - 64 λ + AHi: TUInt64 - 64 λ + B: TUInt64 - + var DivRes: TUInt64 - + var ModRes: TUInt64 - + + ֵޣ +} + +{$ENDIF} + +function IsUInt128BitSet(Lo: TUInt64; Hi: TUInt64; N: Integer): Boolean; +{* Int64 ƴɵ 128 λ֣ص N λǷΪ 1N 0 127 + + + Lo: TUInt64 - жϵĵ 64 λ + Hi: TUInt64 - жϵĸ 64 λ + N: Integer - жϵλ + + ֵBoolean - ǷΪ 1 +} + +procedure SetUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); +{* Int64 ƴɵ 128 λ֣õ N λΪ 1N 0 127 + + + var Lo: TUInt64 - õĵ 64 λ + var Hi: TUInt64 - õĸ 64 λ + N: Integer - õλ + + ֵޣ +} + +procedure ClearUInt128Bit(var Lo: TUInt64; var Hi: TUInt64; N: Integer); +{* Int64 ƴɵ 128 λ֣ N λN 0 127 + + + var Lo: TUInt64 - õĵ 64 λ + var Hi: TUInt64 - õĸ 64 λ + N: Integer - õλ + + ֵޣ +} + +function UnsignedAddWithLimitRadix(A: Cardinal; B: Cardinal; C: Cardinal; + var R: Cardinal; L: Cardinal; H: Cardinal): Cardinal; +{* Ƶ޷żӷA + B + C R Уؽλֵ + ȷ L H ıڣûȷ H LΡ + úַӳ䣬 C һǽλ + + + A: Cardinal - һ + B: Cardinal - + C: Cardinal - һǽλ + var R: Cardinal - + L: Cardinal - ͵ + H: Cardinal - ͵ + + ֵCardinal - Ƿнλ +} + +// =========================== ѭλ ==================================== + +// ע N Ӧ (0, A λ) ڣ N Ϊ 0 A λʱֵӦΪ A +// N ʱࣨΪͲȲͬ 32 λ AN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ + +function RotateLeft16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 16 λѭ N λ + + + A: Word - ѭƵ 16 λ + N: Integer - ѭƵλ + + ֵWord - λֵ +} + +function RotateRight16(A: Word; N: Integer): Word; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 16 λѭ N λ + + + A: Word - ѭƵ 16 λ + N: Integer - ѭƵλ + + ֵWord - λֵ +} + +function RotateLeft32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 32 λѭ N λ + + + A: Cardinal - ѭƵ 32 λ + N: Integer - ѭƵλ + + ֵCardinal - λֵ +} + +function RotateRight32(A: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 32 λѭ N λ + + + A: Cardinal - ѭƵ 32 λ + N: Integer - ѭƵλ + + ֵCardinal - λֵ +} + +function RotateLeft64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 64 λѭ N λ + + + A: TUInt64 - ѭƵ 64 λ + N: Integer - ѭƵλ + + ֵTUInt64 - λֵ +} + +function RotateRight64(A: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +{* 64 λѭ N λ + + + A: TUInt64 - ѭƵ 64 λ + N: Integer - ѭƵλ + + ֵTUInt64 - λֵ +} + +{$IFDEF COMPILER5} + +function BoolToStr(Value: Boolean; UseBoolStrs: Boolean = False): string; +{* תΪַDelphi 5 ûи BoolToStr ϡ + + + Value: Boolean - תIJֵ + UseBoolStrs: Boolean - Ƿ񷵻Ӣĵ + + ֵstring - UseBoolStrs Ϊ False ʱ -1 0򷵻 True False +} + +{$ENDIF} + +implementation + +uses + CnFloat; + +resourcestring + SCnErrorNotAHexPChar = 'Error: NOT a Hex PChar: %c'; + SCnErrorLengthNotHex = 'Error Length %d: NOT a Hex String'; + SCnErrorLengthNotHexAnsi = 'Error Length %d: NOT a Hex AnsiString'; + +var + FByteOrderIsBigEndian: Boolean = False; + +function CurrentByteOrderIsBigEndian: Boolean; +type + TByteOrder = packed record + case Boolean of + False: (C: array[0..1] of Byte); + True: (W: Word); + end; +var + T: TByteOrder; +begin + T.W := $00CC; + Result := T.C[1] = $CC; +end; + +function CurrentByteOrderIsLittleEndian: Boolean; +begin + Result := not CurrentByteOrderIsBigEndian; +end; + +function ReverseInt64(Value: Int64): Int64; +var + Lo, Hi: Cardinal; + Rec: Int64Rec; +begin + Lo := Int64Rec(Value).Lo; + Hi := Int64Rec(Value).Hi; + Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) + or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); + Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) + or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); + Rec.Lo := Hi; + Rec.Hi := Lo; + Result := Int64(Rec); +end; + +function ReverseUInt64(Value: TUInt64): TUInt64; +var + Lo, Hi: Cardinal; + Rec: Int64Rec; +begin + Lo := Int64Rec(Value).Lo; + Hi := Int64Rec(Value).Hi; + Lo := ((Lo and $000000FF) shl 24) or ((Lo and $0000FF00) shl 8) + or ((Lo and $00FF0000) shr 8) or ((Lo and $FF000000) shr 24); + Hi := ((Hi and $000000FF) shl 24) or ((Hi and $0000FF00) shl 8) + or ((Hi and $00FF0000) shr 8) or ((Hi and $FF000000) shr 24); + Rec.Lo := Hi; + Rec.Hi := Lo; + Result := TUInt64(Rec); +end; + +function Int64ToBigEndian(Value: Int64): Int64; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseInt64(Value); +end; + +function Int32ToBigEndian(Value: Integer): Integer; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); +end; + +function Int16ToBigEndian(Value: SmallInt): SmallInt; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); +end; + +function Int64ToLittleEndian(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseInt64(Value); +end; + +function Int32ToLittleEndian(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24); +end; + +function Int16ToLittleEndian(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8); +end; + +function UInt64ToBigEndian(Value: TUInt64): TUInt64; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32ToBigEndian(Value: Cardinal): Cardinal; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); +end; + +function UInt16ToBigEndian(Value: Word): Word; +begin + if FByteOrderIsBigEndian then + Result := Value + else + Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); +end; + +function UInt64ToLittleEndian(Value: TUInt64): TUInt64; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32ToLittleEndian(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24); +end; + +function UInt16ToLittleEndian(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := Value + else + Result := Word((Value and $00FF) shl 8) or Word((Value and $FF00) shr 8); +end; + +function Int64HostToNetwork(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + Result := ReverseInt64(Value) + else + Result := Value; +end; + +function Int32HostToNetwork(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function Int16HostToNetwork(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) + else + Result := Value; +end; + +function Int64NetworkToHost(Value: Int64): Int64; +begin + if not FByteOrderIsBigEndian then + REsult := ReverseInt64(Value) + else + Result := Value; +end; + +function Int32NetworkToHost(Value: Integer): Integer; +begin + if not FByteOrderIsBigEndian then + Result := Integer((Value and $000000FF) shl 24) or Integer((Value and $0000FF00) shl 8) + or Integer((Value and $00FF0000) shr 8) or Integer((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function Int16NetworkToHost(Value: SmallInt): SmallInt; +begin + if not FByteOrderIsBigEndian then + Result := SmallInt((Value and $00FF) shl 8) or SmallInt((Value and $FF00) shr 8) + else + Result := Value; +end; + +function UInt64HostToNetwork(Value: TUInt64): TUInt64; +begin + if CurrentByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32HostToNetwork(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function UInt16HostToNetwork(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) + else + Result := Value; +end; + +function UInt64NetworkToHost(Value: TUInt64): TUInt64; +begin + if CurrentByteOrderIsBigEndian then + Result := Value + else + Result := ReverseUInt64(Value); +end; + +function UInt32NetworkToHost(Value: Cardinal): Cardinal; +begin + if not FByteOrderIsBigEndian then + Result := Cardinal((Value and $000000FF) shl 24) or Cardinal((Value and $0000FF00) shl 8) + or Cardinal((Value and $00FF0000) shr 8) or Cardinal((Value and $FF000000) shr 24) + else + Result := Value; +end; + +function UInt16NetworkToHost(Value: Word): Word; +begin + if not FByteOrderIsBigEndian then + Result := ((Value and $00FF) shl 8) or ((Value and $FF00) shr 8) + else + Result := Value; +end; + +function ReverseBitsInInt8(V: Byte): Byte; +begin + // 0 1 2 3 4 5 6 7 + V := ((V and $AA) shr 1) or ((V and $55) shl 1); + // 01 23 45 67 + V := ((V and $CC) shr 2) or ((V and $33) shl 2); + // 0123 4567 + V := (V shr 4) or (V shl 4); + Result := V; +end; + +function ReverseBitsInInt16(V: Word): Word; +begin + Result := (ReverseBitsInInt8(V and $00FF) shl 8) + or ReverseBitsInInt8((V and $FF00) shr 8); +end; + +function ReverseBitsInInt32(V: Cardinal): Cardinal; +begin + Result := (ReverseBitsInInt16(V and $0000FFFF) shl 16) + or ReverseBitsInInt16((V and $FFFF0000) shr 16); +end; + +function ReverseBitsInInt64(V: Int64): Int64; +begin + Result := (Int64(ReverseBitsInInt32(V and $00000000FFFFFFFF)) shl 32) + or ReverseBitsInInt32((V and $FFFFFFFF00000000) shr 32); +end; + +procedure ReverseMemory(Mem: Pointer; MemByteLen: Integer); +var + I, L: Integer; + P: PByteArray; + T: Byte; +begin + if (Mem = nil) or (MemByteLen < 2) then + Exit; + + L := MemByteLen div 2; + P := PByteArray(Mem); + for I := 0 to L - 1 do + begin + // I ͵ MemLen - I - 1 + T := P^[I]; + P^[I] := P^[MemByteLen - I - 1]; + P^[MemByteLen - I - 1] := T; + end; +end; + +procedure ReverseMemoryWithBits(Mem: Pointer; MemByteLen: Integer); +var + I: Integer; + P: PByteArray; +begin + if (Mem = nil) or (MemByteLen <= 0) then + Exit; + + ReverseMemory(Mem, MemByteLen); + P := PByteArray(Mem); + + for I := 0 to MemByteLen - 1 do + P^[I] := ReverseBitsInInt8(P^[I]); +end; + +procedure MemoryNetworkToHost(Mem: Pointer; MemByteLen: Integer); +begin + if not FByteOrderIsBigEndian then + ReverseMemory(Mem, MemByteLen); +end; + +procedure MemoryHostToNetwork(Mem: Pointer; MemByteLen: Integer); +begin + if not FByteOrderIsBigEndian then + ReverseMemory(Mem, MemByteLen); +end; + +// N ֽڳȵڴλ +procedure MemoryBitOperation(AMem, BMem, RMem: Pointer; N: Integer; Op: TCnBitOperation); +var + A, B, R: PCnLongWord32Array; + BA, BB, BR: PByteArray; +begin + if N <= 0 then + Exit; + + if (AMem = nil) or ((BMem = nil) and (Op <> boNot)) or (RMem = nil) then + Exit; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + R := PCnLongWord32Array(RMem); + + while (N and (not 3)) <> 0 do + begin + case Op of + boAnd: + R^[0] := A^[0] and B^[0]; + boOr: + R^[0] := A^[0] or B^[0]; + boXor: + R^[0] := A^[0] xor B^[0]; + boNot: // ʱ B + R^[0] := not A^[0]; + end; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + R := PCnLongWord32Array(TCnNativeInt(R) + SizeOf(Cardinal)); + + Dec(N, SizeOf(Cardinal)); + end; + + if N > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + BR := PByteArray(R); + + while N <> 0 do + begin + case Op of + boAnd: + BR^[0] := BA^[0] and BB^[0]; + boOr: + BR^[0] := BA^[0] or BB^[0]; + boXor: + BR^[0] := BA^[0] xor BB^[0]; + boNot: + BR^[0] := not BA^[0]; + end; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + BR := PByteArray(TCnNativeInt(BR) + SizeOf(Byte)); + Dec(N); + end; + end; +end; + +procedure MemoryAnd(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boAnd); +end; + +procedure MemoryOr(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boOr); +end; + +procedure MemoryXor(AMem, BMem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(AMem, BMem, ResMem, MemByteLen, boXor); +end; + +procedure MemoryNot(Mem: Pointer; MemByteLen: Integer; ResMem: Pointer); +begin + MemoryBitOperation(Mem, nil, ResMem, MemByteLen, boNot); +end; + +procedure MemoryShiftLeft(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +var + I, L, N, LB, RB: Integer; + PF, PT: PByteArray; +begin + if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then + Exit; + + if BitCount < 0 then + begin + MemoryShiftRight(AMem, BMem, MemByteLen, -BitCount); + Exit; + end; + + if BMem = nil then + BMem := AMem; + + if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 + begin + FillChar(BMem^, MemByteLen, 0); + Exit; + end; + + N := BitCount div 8; // λֽ + RB := BitCount mod 8; // ȥֽںʣµλ + LB := 8 - RB; // ʣµλһֽʣµλ + + PF := PByteArray(AMem); + PT := PByteArray(BMem); + + if RB = 0 then // 飬ð죬Ҫλֽ MemLen - NW + begin + Move(PF^[N], PT^[0], MemByteLen - N); + FillChar(PT^[MemByteLen - N], N, 0); + end + else + begin + // PF^[N] PT^[0] MemLen - N ֽڣֽڼн + L := MemByteLen - N; + PF := PByteArray(TCnNativeInt(PF) + N); + + for I := 1 to L do // ӵλƶȴ͵ + begin + PT^[0] := Byte(PF^[0] shl RB); + if I < L then // һֽ PF^[1] ᳬ + PT^[0] := (PF^[1] shr LB) or PT^[0]; + + PF := PByteArray(TCnNativeInt(PF) + 1); + PT := PByteArray(TCnNativeInt(PT) + 1); + end; + + // ʣµҪ 0 + if N > 0 then + FillChar(PT^[0], N, 0); + end; +end; + +procedure MemoryShiftRight(AMem, BMem: Pointer; MemByteLen: Integer; BitCount: Integer); +var + I, L, N, LB, RB: Integer; + PF, PT: PByteArray; +begin + if (AMem = nil) or (MemByteLen <= 0) or (BitCount = 0) then + Exit; + + if BitCount < 0 then + begin + MemoryShiftLeft(AMem, BMem, MemByteLen, -BitCount); + Exit; + end; + + if BMem = nil then + BMem := AMem; + + if (MemByteLen * 8) <= BitCount then // ̫಻ȫ 0 + begin + FillChar(BMem^, MemByteLen, 0); + Exit; + end; + + N := BitCount div 8; // λֽ + RB := BitCount mod 8; // ȥֽںʣµλ + LB := 8 - RB; // ʣµλһֽʣµλ + + if RB = 0 then // 飬ð죬Ҫλֽ MemLen - N + begin + PF := PByteArray(AMem); + PT := PByteArray(BMem); + + Move(PF^[0], PT^[N], MemByteLen - N); + FillChar(PT^[0], N, 0); + end + else + begin + // PF^[0] PT^[N] MemLen - N ֽڣôӸߴʼֽڼн + L := MemByteLen - N; + + PF := PByteArray(TCnNativeInt(AMem) + L - 1); + PT := PByteArray(TCnNativeInt(BMem) + MemByteLen - 1); + + for I := L downto 1 do // Ӹλλƶȴ + begin + PT^[0] := Byte(PF^[0] shr RB); + if I > 1 then // һֽ PF^[-1] ᳬ + begin + PF := PByteArray(TCnNativeInt(PF) - 1); + PT^[0] := (PF^[0] shl LB) or PT^[0]; + end + else + PF := PByteArray(TCnNativeInt(PF) - 1); + + PT := PByteArray(TCnNativeInt(PT) - 1); + end; + + // ʣµǰҪ 0 + if N > 0 then + FillChar(BMem^, N, 0); + end; +end; + +function MemoryIsBitSet(Mem: Pointer; N: Integer): Boolean; +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := Byte(1 shl B); + Result := (P^ and V) <> 0; +end; + +procedure MemorySetBit(Mem: Pointer; N: Integer); +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := Byte(1 shl B); + P^ := P^ or V; +end; + +procedure MemoryClearBit(Mem: Pointer; N: Integer); +var + P: PByte; + A, B: Integer; + V: Byte; +begin + if (Mem = nil) or (N < 0) then + raise ERangeError.Create(SRangeError); + + A := N div 8; + B := N mod 8; + P := PByte(TCnNativeInt(Mem) + A); + + V := not Byte(1 shl B); + P^ := P^ and V; +end; + +function MemoryToBinStr(Mem: Pointer; MemByteLen: Integer; Sep: Boolean): string; +var + J, L: Integer; + P: PByteArray; + B: PChar; + + procedure FillAByteToBuf(V: Byte; Buf: PChar); + const + M = $80; + var + I: Integer; + begin + for I := 0 to 7 do + begin + if (V and M) <> 0 then + Buf[I] := '1' + else + Buf[I] := '0'; + V := V shl 1; + end; + end; + +begin + Result := ''; + if (Mem = nil) or (MemByteLen <= 0) then + Exit; + + L := MemByteLen * 8; + if Sep then + L := L + MemByteLen - 1; // мÿոָ + + SetLength(Result, L); + B := PChar(@Result[1]); + P := PByteArray(Mem); + + for J := 0 to MemByteLen - 1 do + begin + FillAByteToBuf(P^[J], B); + if Sep then + begin + B[8] := ' '; + Inc(B, 9); + end + else + Inc(B, 8); + end; +end; + +procedure MemorySwap(AMem, BMem: Pointer; MemByteLen: Integer); +var + A, B: PCnLongWord32Array; + BA, BB: PByteArray; + TC: Cardinal; + TB: Byte; +begin + if (AMem = nil) or (BMem = nil) or (MemByteLen <= 0) then + Exit; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + + if A = B then + Exit; + + while (MemByteLen and (not 3)) <> 0 do + begin + TC := A^[0]; + A^[0] := B^[0]; + B^[0] := TC; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + + Dec(MemByteLen, SizeOf(Cardinal)); + end; + + if MemByteLen > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + + while MemByteLen <> 0 do + begin + TB := BA^[0]; + BA^[0] := BB^[0]; + BB^[0] :=TB; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + + Dec(MemByteLen); + end; + end; +end; + +function MemoryCompare(AMem, BMem: Pointer; MemByteLen: Integer): Integer; +var + A, B: PCnLongWord32Array; + BA, BB: PByteArray; +begin + Result := 0; + if ((AMem = nil) and (BMem = nil)) or (AMem = BMem) then // ͬһ + Exit; + + if MemByteLen <= 0 then + Exit; + + if AMem = nil then + begin + Result := -1; + Exit; + end; + if BMem = nil then + begin + Result := 1; + Exit; + end; + + A := PCnLongWord32Array(AMem); + B := PCnLongWord32Array(BMem); + + while (MemByteLen and (not 3)) <> 0 do + begin + if A^[0] > B^[0] then + begin + Result := 1; + Exit; + end + else if A^[0] < B^[0] then + begin + Result := -1; + Exit; + end; + + A := PCnLongWord32Array(TCnNativeInt(A) + SizeOf(Cardinal)); + B := PCnLongWord32Array(TCnNativeInt(B) + SizeOf(Cardinal)); + + Dec(MemByteLen, SizeOf(Cardinal)); + end; + + if MemByteLen > 0 then + begin + BA := PByteArray(A); + BB := PByteArray(B); + + while MemByteLen <> 0 do + begin + if BA^[0] > BB^[0] then + begin + Result := 1; + Exit; + end + else if BA^[0] < BB^[0] then + begin + Result := -1; + Exit; + end; + + BA := PByteArray(TCnNativeInt(BA) + SizeOf(Byte)); + BB := PByteArray(TCnNativeInt(BB) + SizeOf(Byte)); + + Dec(MemByteLen); + end; + end; +end; + +function UInt8ToBinStr(V: Byte): string; +const + M = $80; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt16ToBinStr(V: Word): string; +const + M = $8000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt32ToBinStr(V: Cardinal): string; +const + M = $80000000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +function UInt32ToStr(V: Cardinal): string; +begin + Result := Format('%u', [V]); +end; + +function UInt64ToBinStr(V: TUInt64): string; +const + M = $8000000000000000; +var + I: Integer; +begin + SetLength(Result, 8 * SizeOf(V)); + + for I := 1 to 8 * SizeOf(V) do + begin + if (V and M) <> 0 then + Result[I] := '1' + else + Result[I] := '0'; + V := V shl 1; + end; +end; + +const + HiDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); +const + LoDigits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +const + AnsiHiDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); +const + AnsiLoDigits: array[0..15] of AnsiChar = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'); + +function HexToInt(Hex: PChar; CharLen: Integer): Integer; +var + I, Res: Integer; + C: Char; +begin + Res := 0; + for I := 0 to CharLen - 1 do + begin + C := Hex[I]; + if (C >= '0') and (C <= '9') then + Res := Res * 16 + Ord(C) - Ord('0') + else if (C >= 'A') and (C <= 'F') then + Res := Res * 16 + Ord(C) - Ord('A') + 10 + else if (C >= 'a') and (C <= 'f') then + Res := Res * 16 + Ord(C) - Ord('a') + 10 + else + raise ECnNativeException.CreateFmt(SCnErrorNotAHexPChar, [C]); + end; + Result := Res; +end; + +function HexToInt(const Hex: string): Integer; +begin + Result := HexToInt(PChar(Hex), Length(Hex)); +end; + +{$WARNINGS OFF} + +function IsHexString(const Hex: string): Boolean; +var + I, L: Integer; +begin + Result := False; + L := Length(Hex); + if (L <= 0) or ((L and 1) <> 0) then // ջżȶ + Exit; + + for I := 1 to L do + begin + // ע˴ Unicode Ȼ Warningǽ Hex[I] WideChar ֱӽض AnsiChar + // ٽжϣᵼ¡޻ޡ $66$66$66$66 ַУ + // ֱͨ WideChar ֵ ax ˫ֽڵģӼжϣ + if not (Hex[I] in ['0'..'9', 'A'..'F', 'a'..'f']) then + Exit; + end; + Result := True; +end; + +{$WARNINGS ON} + +function DataToHex(InData: Pointer; ByteLength: Integer; UseUpperCase: Boolean = True): string; +var + I: Integer; + B: Byte; +begin + Result := ''; + if ByteLength <= 0 then + Exit; + + SetLength(Result, ByteLength * 2); + if UseUpperCase then + begin + for I := 0 to ByteLength - 1 do + begin + B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to ByteLength - 1 do + begin + B := PByte(TCnNativeInt(InData) + I * SizeOf(Byte))^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToData(const Hex: string; OutData: Pointer): Integer; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + if OutData = nil then + begin + Result := L div 2; + Exit; + end; + + Result := 0; + H := PChar(Hex); + for I := 1 to L div 2 do + begin + PByte(TCnNativeInt(OutData) + I - 1)^ := Byte(HexToInt(@H[(I - 1) * 2], 2)); + Inc(Result); + end; +end; + +function StringToHex(const Data: string; UseUpperCase: Boolean): string; +var + I, L: Integer; + B: Byte; + Buffer: PChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[1]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I * SizeOf(Char))^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToString(const Hex: string): string; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + SetLength(Result, L div 2); + H := PChar(Hex); + for I := 1 to L div 2 do + Result[I] := Chr(HexToInt(@H[(I - 1) * 2], 2)); +end; + +function HexToAnsiStr(const Hex: AnsiString): AnsiString; +var + I, L: Integer; + S: string; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHexAnsi, [L]); + + SetLength(Result, L div 2); + for I := 1 to L div 2 do + begin + S := string(Copy(Hex, I * 2 - 1, 2)); + Result[I] := AnsiChar(Chr(HexToInt(S))); + end; +end; + +function AnsiStrToHex(const Data: AnsiString; UseUpperCase: Boolean): AnsiString; +var + I, L: Integer; + B: Byte; + Buffer: PAnsiChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[1]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := AnsiHiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := AnsiHiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := AnsiLoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := AnsiLoDigits[B and $0F]; + end; + end; +end; + +function BytesToHex(Data: TBytes; UseUpperCase: Boolean): string; +var + I, L: Integer; + B: Byte; + Buffer: PAnsiChar; +begin + Result := ''; + L := Length(Data); + if L = 0 then + Exit; + + SetLength(Result, L * 2); + Buffer := @Data[0]; + + if UseUpperCase then + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := HiDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := HiDigits[B and $0F]; + end; + end + else + begin + for I := 0 to L - 1 do + begin + B := PByte(TCnNativeInt(Buffer) + I)^; + Result[I * 2 + 1] := LoDigits[(B shr 4) and $0F]; + Result[I * 2 + 2] := LoDigits[B and $0F]; + end; + end; +end; + +function HexToBytes(const Hex: string): TBytes; +var + I, L: Integer; + H: PChar; +begin + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + SetLength(Result, L div 2); + H := PChar(Hex); + + for I := 1 to L div 2 do + Result[I - 1] := Byte(HexToInt(@H[(I - 1) * 2], 2)); +end; + +function StreamToHex(Stream: TStream; UseUpperCase: Boolean): string; +var + B: Byte; + I: Integer; +begin + Result := ''; + if Stream.Size > 0 then + begin + Stream.Position := 0; + SetLength(Result, Stream.Size * 2); + I := 1; + if UseUpperCase then + begin + while Stream.Read(B, 1) = 1 do + begin + Result[I] := HiDigits[(B shr 4) and $0F]; + Inc(I); + Result[I] := HiDigits[B and $0F]; + Inc(I); + end; + end + else + begin + while Stream.Read(B, 1) = 1 do + begin + Result[I] := LoDigits[(B shr 4) and $0F]; + Inc(I); + Result[I] := LoDigits[B and $0F]; + Inc(I); + end; + end; + end; +end; + +function HexToStream(const Hex: string; Stream: TStream): Integer; +var + I, L: Integer; + H: PChar; + B: Byte; +begin + Result := 0; + L := Length(Hex); + if (L mod 2) <> 0 then + raise ECnNativeException.CreateFmt(SCnErrorLengthNotHex, [L]); + + H := PChar(Hex); + for I := 1 to L div 2 do + begin + B := Byte(HexToInt(@H[(I - 1) * 2], 2)); + Inc(Result, Stream.Write(B, 1)); + end; +end; + +procedure ReverseBytes(Data: TBytes); +var + I, L, M: Integer; + T: Byte; +begin + if (Data = nil) or (Length(Data) <= 1) then + Exit; + L := Length(Data); + M := L div 2; + for I := 0 to M - 1 do + begin + // I L - I - 1 + T := Data[I]; + Data[I] := Data[L - I - 1]; + Data[L - I - 1] := T; + end; +end; + +function CloneBytes(Data: TBytes): TBytes; +begin + if Length(Data) = 0 then + Result := nil + else + begin + SetLength(Result, Length(Data)); + Move(Data[0], Result[0], Length(Data)); + end; +end; + +function StreamToBytes(Stream: TStream): TBytes; +begin + Result := nil; + if (Stream <> nil) and (Stream.Size > 0) then + begin + SetLength(Result, Stream.Size); + Stream.Position := 0; + Stream.Read(Result[0], Stream.Size); + end; +end; + +function BytesToStream(Data: TBytes; OutStream: TStream): Integer; +begin + Result := 0; + if (Data <> nil) and (Length(Data) > 0) and (OutStream <> nil) then + begin + OutStream.Size := 0; + Result := OutStream.Write(Data[0], Length(Data)); + end; +end; + +function AnsiToBytes(const Str: AnsiString): TBytes; +begin + SetLength(Result, Length(Str)); + if Length(Str) > 0 then + Move(Str[1], Result[0], Length(Str)); +end; + +function BytesToAnsi(Data: TBytes): AnsiString; +begin + SetLength(Result, Length(Data)); + if Length(Data) > 0 then + Move(Data[0], Result[1], Length(Data)); +end; + +function BytesToString(Data: TBytes): string; +var + I: Integer; +begin + SetLength(Result, Length(Data)); + for I := 1 to Length(Data) do + Result[I] := Chr(Data[I - 1]); +end; + +function MemoryToString(Mem: Pointer; MemByteLen: Integer): string; +var + P: PByteArray; + I: Integer; +begin + if (Mem = nil) or (MemByteLen <= 0) then + begin + Result := ''; + Exit; + end; + + P := PByteArray(Mem); + SetLength(Result, MemByteLen); + for I := 1 to MemByteLen do + Result[I] := Chr(P^[I - 1]); +end; + +function BitsToString(Bits: TBits): string; +var + I: Integer; +begin + if (Bits = nil) or (Bits.Size = 0) then + Result := '' + else + begin + SetLength(Result, Bits.Size); + for I := 0 to Bits.Size - 1 do + begin + if Bits.Bits[I] then + Result[I + 1] := '1' + else + Result[I + 1] := '0'; + end; + end; +end; + +function ConcatBytes(A, B: TBytes): TBytes; +begin + // XE7 ҲֱӣΪ A B Ϊʱ᷵һֽ + if (A = nil) or (Length(A) = 0) then + begin + SetLength(Result, Length(B)); + if Length(B) > 0 then + Move(B[0], Result[0], Length(B)); + end + else if (B = nil) or (Length(B) = 0) then + begin + SetLength(Result, Length(A)); + if Length(A) > 0 then + Move(A[0], Result[0], Length(A)); + end + else + begin + SetLength(Result, Length(A) + Length(B)); + Move(A[0], Result[0], Length(A)); + Move(B[0], Result[Length(A)], Length(B)); + end; +end; + +function NewBytesFromMemory(Data: Pointer; DataByteLen: Integer): TBytes; +begin + if (Data = nil) or (DataByteLen <= 0) then + Result := nil + else + begin + SetLength(Result, DataByteLen); + Move(Data^, Result[0], DataByteLen); + end; +end; + +function CompareBytes(A, B: TBytes): Boolean; +var + L: Integer; +begin + Result := False; + + L := Length(A); + if Length(B) <> L then // Ȳ˳ + Exit; + + if L = 0 then // + Result := True // 綼 0 + else + Result := CompareMem(@A[0], @B[0], L); +end; + +function CompareBytes(A, B: TBytes; MaxLength: Integer): Boolean; +var + LA, LB: Integer; +begin + Result := False; + + LA := Length(A); + LB := Length(B); + + if LA > MaxLength then + LA := MaxLength; + if LB > MaxLength then + LB := MaxLength; + + if LA <> LB then + Exit; + + if LA = 0 then + Result := True + else + Result := CompareMem(@A[0], @B[0], LA); +end; + +function MoveMost(const Source; var Dest; ByteLen, MostLen: Integer): Integer; +begin + if (MostLen <= 0) or (ByteLen <= 0) then + begin + Result := 0; + Exit; + end; + + if ByteLen > MostLen then + ByteLen := MostLen + else if ByteLen < MostLen then + begin + FillChar(Dest, MostLen, 0); + + // TODO: ҪΪ FillChar(Dest + ByteLen, MostLen - ByteLen, 0); ֻ䲻IJ + end; + + Move(Source, Dest, ByteLen); + Result := ByteLen; +end; + +// =============================== =================================== + +function SarInt8(var V: Byte; ShiftCount: Integer): Byte; +begin + Result := V shr ShiftCount; + if (V and $80) <> 0 then + Result := Result or $80; +end; + +function SarInt16(var V: Word; ShiftCount: Integer): Word; +begin + Result := V shr ShiftCount; + if (V and $8000) <> 0 then + Result := Result or $8000; +end; + +function SarInt32(var V: Cardinal; ShiftCount: Integer): Cardinal; +begin + Result := V shr ShiftCount; + if (V and $80000000) <> 0 then + Result := Result or $80000000; +end; + +function SarInt64(var V: TUInt64; ShiftCount: Integer): TUInt64; +begin + Result := V shr ShiftCount; + if (V and $8000000000000000) <> 0 then + Result := Result or $8000000000000000; +end; + +procedure ConstTimeConditionalSwap8(CanSwap: Boolean; var A, B: Byte); +var + T, V: Byte; +begin + T := ConstTimeExpandBoolean8(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap16(CanSwap: Boolean; var A, B: Word); +var + T, V: Word; +begin + T := ConstTimeExpandBoolean16(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap32(CanSwap: Boolean; var A, B: Cardinal); +var + T, V: Cardinal; +begin + T := ConstTimeExpandBoolean32(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +procedure ConstTimeConditionalSwap64(CanSwap: Boolean; var A, B: TUInt64); +var + T, V: TUInt64; +begin + T := ConstTimeExpandBoolean64(CanSwap); + V := (A xor B) and T; + A := A xor V; + B := B xor V; +end; + +function ConstTimeEqual8(A, B: Byte): Boolean; +var + R: Byte; +begin + R := not (A xor B); // + R := R and (R shr 4); // һһ + R := R and (R shr 2); // һλ 0 + R := R and (R shr 1); // 0 + Result := Boolean(R); // ֻȫ 1 1 +end; + +function ConstTimeEqual16(A, B: Word): Boolean; +begin + Result := ConstTimeEqual8(Byte(A shr 8), Byte(B shr 8)) + and ConstTimeEqual8(Byte(A and $FF), Byte(B and $FF)); +end; + +function ConstTimeEqual32(A, B: Cardinal): Boolean; +begin + Result := ConstTimeEqual16(Word(A shr 16), Word(B shr 16)) + and ConstTimeEqual16(Word(A and $FFFF), Word(B and $FFFF)); +end; + +function ConstTimeEqual64(A, B: TUInt64): Boolean; +begin + Result := ConstTimeEqual32(Cardinal(A shr 32), Cardinal(B shr 32)) + and ConstTimeEqual32(Cardinal(A and $FFFFFFFF), Cardinal(B and $FFFFFFFF)); +end; + +function ConstTimeBytesEqual(A, B: TBytes): Boolean; +var + I: Integer; +begin + Result := False; + if Length(A) <> Length(B) then + Exit; + + Result := True; + for I := 0 to Length(A) - 1 do // ÿֽڶȽϣͬ˳ + Result := Result and (ConstTimeEqual8(A[I], B[I])); +end; + +function ConstTimeExpandBoolean8(V: Boolean): Byte; +begin + Result := Byte(V); + Result := not Result; // V True 0˲ R Ǵ $FFR ͷ 0 + Result := Result and (Result shr 4); // һһ + Result := Result and (Result shr 2); // һλ 0 + Result := Result and (Result shr 1); // 00000000 00000001 + Result := Result or (Result shl 1); // True õ 00000000False õ 00000001λ + Result := Result or (Result shl 2); + Result := Result or (Result shl 4); // ȫ 0 ȫ 1 + Result := not Result; // ȫ 1 ȫ 0 +end; + +function ConstTimeExpandBoolean16(V: Boolean): Word; +var + R: Byte; +begin + R := ConstTimeExpandBoolean8(V); + Result := R; + Result := (Result shl 8) or R; // ֽȫ 1 ȫ 0 ˫ֽ +end; + +function ConstTimeExpandBoolean32(V: Boolean): Cardinal; +var + R: Word; +begin + R := ConstTimeExpandBoolean16(V); + Result := R; + Result := (Result shl 16) or R; // ˫ֽȫ 1 ȫ 0 ֽ +end; + +function ConstTimeExpandBoolean64(V: Boolean): TUInt64; +var + R: Cardinal; +begin + R := ConstTimeExpandBoolean32(V); + Result := R; + Result := (Result shl 32) or R; // ֽȫ 1 ȫ 0 ɰֽ +end; + +function ConstTimeConditionalSelect8(Condition: Boolean; A, B: Byte): Byte; +begin + ConstTimeConditionalSwap8(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect16(Condition: Boolean; A, B: Word): Word; +begin + ConstTimeConditionalSwap16(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect32(Condition: Boolean; A, B: Cardinal): Cardinal; +begin + ConstTimeConditionalSwap32(Condition, A, B); + Result := B; +end; + +function ConstTimeConditionalSelect64(Condition: Boolean; A, B: TUInt64): TUInt64; +begin + ConstTimeConditionalSwap64(Condition, A, B); + Result := B; +end; + +{$IFDEF MSWINDOWS} + +{$IFDEF CPUX64} + +// 64 λ IDIV IDIV ָʵ֣ A RCX B EDX/RDX DivRes ַ R8 ModRes ַ R9 +procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; +asm + PUSH RCX // RCX A + MOV RCX, RDX // B RCX + POP RAX // A RAX + XOR RDX, RDX // 64 λ + IDIV RCX + MOV [R8], EAX // ̷ R8 ָ DivRes + MOV [R9], EDX // R9 ָ ModRes +end; + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; +asm + PUSH RCX // RCX A + MOV RCX, RDX // B RCX + POP RAX // A RAX + XOR RDX, RDX // 64 λ + DIV RCX + MOV [R8], EAX // ̷ R8 ָ DivRes + MOV [R9], EDX // R9 ָ ModRes +end; + +// 64 λ IDIV IDIV ָʵ֣ALo RCXAHi RDXB R8DivRes ĵַ R9 +procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); assembler; +asm + MOV RAX, RCX // ALo RAXAHi Ѿ RDX + MOV RCX, R8 // B RCX + IDIV RCX + MOV [R9], RAX // ̷ R9 ָ DivRes + MOV RAX, [RBP + $30] // ModRes ַ RAX + MOV [RAX], RDX // RAX ָ ModRes +end; + +procedure UInt128DivUInt64Mod(ALo, AHi: UInt64; B: UInt64; var DivRes, ModRes: UInt64); assembler; +asm + MOV RAX, RCX // ALo RAXAHi Ѿ RDX + MOV RCX, R8 // B RCX + DIV RCX + MOV [R9], RAX // ̷ R9 ָ DivRes + MOV RAX, [RBP + $30] // ModRes ַ RAX + MOV [RAX], RDX // RAX ָ ModRes +end; + +{$ELSE} + +// 32 λ IDIV IDIV ָʵ֣ A ڶջϣB EAXDivRes ַ EDXModRes ַ ECX +procedure Int64DivInt32Mod(A: Int64; B: Integer; var DivRes, ModRes: Integer); assembler; +asm + PUSH ECX // ECX ModRes ַȱ + MOV ECX, B // B EAX УƵ ECX + PUSH EDX // DivRes ĵַ EDX УҲ + MOV EAX, [EBP + $8] // A Lo + MOV EDX, [EBP + $C] // A Hi + IDIV ECX + POP ECX // ECXõ DivRes ַ + MOV [ECX], EAX + POP ECX // ECXõ ModRes ַ + MOV [ECX], EDX +end; + +procedure UInt64DivUInt32Mod(A: TUInt64; B: Cardinal; var DivRes, ModRes: Cardinal); assembler; +asm + PUSH ECX // ECX ModRes ַȱ + MOV ECX, B // B EAX УƵ ECX + PUSH EDX // DivRes ĵַ EDX УҲ + MOV EAX, [EBP + $8] // A Lo + MOV EDX, [EBP + $C] // A Hi + DIV ECX + POP ECX // ECXõ DivRes ַ + MOV [ECX], EAX + POP ECX // ECXõ ModRes ַ + MOV [ECX], EDX +end; + +// 32 λµʵ +procedure Int128DivInt64Mod(ALo, AHi: Int64; B: Int64; var DivRes, ModRes: Int64); +var + C: Integer; +begin + if B = 0 then + raise EDivByZero.Create(SDivByZero); + + if (AHi = 0) or (AHi = $FFFFFFFFFFFFFFFF) then // 64 λΪ 0 ֵֵ + begin + DivRes := ALo div B; + ModRes := ALo mod B; + end + else + begin + if B < 0 then // Ǹ + begin + Int128DivInt64Mod(ALo, AHi, -B, DivRes, ModRes); + DivRes := -DivRes; + Exit; + end; + + if AHi < 0 then // Ǹ + begin + // AHi, ALo 󷴼 1Եõֵ + AHi := not AHi; + ALo := not ALo; +{$IFDEF SUPPORT_UINT64} + UInt64Add(UInt64(ALo), UInt64(ALo), 1, C); +{$ELSE} + UInt64Add(ALo, ALo, 1, C); +{$ENDIF} + if C > 0 then + AHi := AHi + C; + + // ת + Int128DivInt64Mod(ALo, AHi, B, DivRes, ModRes); + + // ٵ + if ModRes = 0 then + DivRes := -DivRes + else + begin + DivRes := -DivRes - 1; + ModRes := B - ModRes; + end; + Exit; + end; + + // ȫ󣬰޷ +{$IFDEF SUPPORT_UINT64} + UInt128DivUInt64Mod(TUInt64(ALo), TUInt64(AHi), TUInt64(B), TUInt64(DivRes), TUInt64(ModRes)); +{$ELSE} + UInt128DivUInt64Mod(ALo, AHi, B, DivRes, ModRes); +{$ENDIF} + end; +end; + +procedure UInt128DivUInt64Mod(ALo, AHi: TUInt64; B: TUInt64; var DivRes, ModRes: TUInt64); +var + I, Cnt: Integer; + Q, R: TUInt64; +begin + if B = 0 then + raise EDivByZero.Create(SDivByZero); + + if AHi = 0 then + begin + DivRes := UInt64Div(ALo, B); + ModRes := UInt64Mod(ALo, B); + end + else + begin + // иλеλզ죿жǷ AHi >= BʾҪ 64 λ + if UInt64Compare(AHi, B) >= 0 then + raise EIntOverflow.Create(SIntOverflow); + + Q := 0; + R := 0; + Cnt := GetUInt64LowBits(AHi) + 64; + for I := Cnt downto 0 do + begin + R := R shl 1; + if IsUInt128BitSet(ALo, AHi, I) then // ĵ I λǷ 0 + R := R or 1 + else + R := R and TUInt64(not 1); + + if UInt64Compare(R, B) >= 0 then + begin + R := R - B; + Q := Q or (TUInt64(1) shl I); + end; + end; + DivRes := Q; + ModRes := R; + end; +end; + +{$ENDIF} + +{$ENDIF} + +{$IFDEF SUPPORT_UINT64} + +// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ + +function UInt64Mod(A, B: TUInt64): TUInt64; +begin + Result := A mod B; +end; + +function UInt64Div(A, B: TUInt64): TUInt64; +begin + Result := A div B; +end; + +{$ELSE} +{ + ֧ UInt64 ĵͰ汾 Delphi Int64 A mod/div B + + õջ˳ A ĸλA ĵλB ĸλB ĵλ push ϲ뺯 + ESP ǷصַESP+4 B ĵλESP + 8 B ĸλESP + C A ĵλESP + 10 A ĸλ + push esp ESP 4Ȼ mov ebp esp֮ EBP ѰַȫҪ 4 + + System.@_llumod ҪڸսʱEAX <- A ĵλEDX <- A ĸλSystem Դע EAX/EDX дˣ + [ESP + 8]Ҳ EBP + C<- B ĸλ[ESP + 4] Ҳ EBP + 8<- B ĵλ + + CALL ǰľƴ롣UInt64 Div Ҳ +} +function UInt64Mod(A, B: TUInt64): TUInt64; +asm + // PUSH ESP ESP 4Ҫ + MOV EAX, [EBP + $10] // A Lo + MOV EDX, [EBP + $14] // A Hi + PUSH DWORD PTR[EBP + $C] // B Hi + PUSH DWORD PTR[EBP + $8] // B Lo + CALL System.@_llumod; +end; + +function UInt64Div(A, B: TUInt64): TUInt64; +asm + // PUSH ESP ESP 4Ҫ + MOV EAX, [EBP + $10] // A Lo + MOV EDX, [EBP + $14] // A Hi + PUSH DWORD PTR[EBP + $C] // B Hi + PUSH DWORD PTR[EBP + $8] // B Lo + CALL System.@_lludiv; +end; + +{$ENDIF} + +{$IFDEF SUPPORT_UINT64} + +// ֻҪ֧ 64 λ޷ 32/64 λ Intel ARM Delphi FPCʲôϵͳ + +function UInt64Mul(A, B: Cardinal): TUInt64; +begin + Result := TUInt64(A) * B; +end; + +{$ELSE} // ֻеͰ汾 Delphi Win32 x86 + +{ + ޷ 32 λˣֱʹ Int64 ģ 64 λ޷ + + üĴԼ A -> EAXB -> EDXʹöջ + System.@_llmul ҪڸսʱEAX <- A ĵλEDX <- A ĸλ 0 + [ESP + 8]Ҳ EBP + C<- B ĸλ 0[ESP + 4] Ҳ EBP + 8<- B ĵλ +} +function UInt64Mul(A, B: Cardinal): TUInt64; +asm + PUSH 0 // PUSH B λ 0 + PUSH EDX // PUSH B λ + // EAX A λѾ + XOR EDX, EDX // EDX A λ 0 + CALL System.@_llmul; // EAX 32 λEDX 32 λ +end; + +{$ENDIF} + +// ޷ 64 λӣ ResLo ResHi +procedure UInt64AddUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); +var + X, Y, Z, T, R0L, R0H, R1L, R1H: Cardinal; + R0, R1, R01, R12: TUInt64; +begin + // ˼룺2^32 ϵ M (xM+y) + (zM+t) = (x+z) M + (y+t) + // y+t R0 ռ 01x+z R1 ռ 12 R0, R1 ٲӳ R01, R12 + if IsUInt64AddOverflow(A, B) then + begin + X := Int64Rec(A).Hi; + Y := Int64Rec(A).Lo; + Z := Int64Rec(B).Hi; + T := Int64Rec(B).Lo; + + R0 := TUInt64(Y) + TUInt64(T); + R1 := TUInt64(X) + TUInt64(Z); + + R0L := Int64Rec(R0).Lo; + R0H := Int64Rec(R0).Hi; + R1L := Int64Rec(R1).Lo; + R1H := Int64Rec(R1).Hi; + + R01 := TUInt64(R0H) + TUInt64(R1L); + R12 := TUInt64(R1H) + TUInt64(Int64Rec(R01).Hi); + + Int64Rec(ResLo).Lo := R0L; + Int64Rec(ResLo).Hi := Int64Rec(R01).Lo; + Int64Rec(ResHi).Lo := Int64Rec(R12).Lo; + Int64Rec(ResHi).Hi := Int64Rec(R12).Hi; + end + else + begin + ResLo := A + B; + ResHi := 0; + end; +end; + +{$IFDEF WIN64} // ע Linux 64 ²֧ ASMֻ WIN64 + +// 64 λ޷ 64 λˣ ResLo ResHi Уֱûʵ֣һ +procedure UInt64MulUInt64(A, B: UInt64; var ResLo, ResHi: UInt64); assembler; +asm + PUSH RAX + MOV RAX, RCX + MUL RDX // ޷ţзŵ IMUL + MOV [R8], RAX + MOV [R9], RDX + POP RAX +end; + +{$ELSE} + +// ޷ 64 λˣ ResLo ResHi +procedure UInt64MulUInt64(A, B: TUInt64; var ResLo, ResHi: TUInt64); +var + X, Y, Z, T: Cardinal; + YT, XT, ZY, ZX: TUInt64; + P, R1Lo, R1Hi, R2Lo, R2Hi: TUInt64; +begin + // ˼룺2^32 ϵ M (xM+y)*(zM+t) = xzM^2 + (xt+yz)M + yt + // ϵ UInt64xz ռ 234xt+yz ռ 123yt ռ 01Ȼۼ + X := Int64Rec(A).Hi; + Y := Int64Rec(A).Lo; + Z := Int64Rec(B).Hi; + T := Int64Rec(B).Lo; + + YT := UInt64Mul(Y, T); + XT := UInt64Mul(X, T); + ZY := UInt64Mul(Y, Z); + ZX := UInt64Mul(X, Z); + + Int64Rec(ResLo).Lo := Int64Rec(YT).Lo; + + P := Int64Rec(YT).Hi; + UInt64AddUInt64(P, XT, R1Lo, R1Hi); + UInt64AddUInt64(ZY, R1Lo, R2Lo, R2Hi); + + Int64Rec(ResLo).Hi := Int64Rec(R2Lo).Lo; + + P := TUInt64(Int64Rec(R2Lo).Hi) + TUInt64(Int64Rec(ZX).Lo); + + Int64Rec(ResHi).Lo := Int64Rec(P).Lo; + Int64Rec(ResHi).Hi := Int64Rec(R1Hi).Lo + Int64Rec(R2Hi).Lo + Int64Rec(ZX).Hi + Int64Rec(P).Hi; +end; + +{$ENDIF} + +{$HINTS OFF} + +function _ValUInt64(const S: string; var Code: Integer): TUInt64; +const + FirstIndex = 1; +var + I: Integer; + Dig: Integer; + Sign: Boolean; + Empty: Boolean; +begin + I := FirstIndex; + Dig := 0; + Result := 0; + + if S = '' then + begin + Code := 1; + Exit; + end; + + while S[I] = Char(' ') do + Inc(I); + Sign := False; + + if S[I] = Char('-') then + begin + Sign := True; + Inc(I); + end + else if S[I] = Char('+') then + Inc(I); + Empty := True; + + if (S[I] = Char('$')) or (UpCase(S[I]) = Char('X')) + or ((S[I] = Char('0')) and (I < Length(S)) and (UpCase(S[I+1]) = Char('X'))) then + begin + if S[I] = Char('0') then + Inc(I); + Inc(I); + while True do + begin + case Char(S[I]) of + Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); + Char('A').. Char('F'): Dig := Ord(S[I]) - (Ord('A') - 10); + Char('a').. Char('f'): Dig := Ord(S[I]) - (Ord('a') - 10); + else + Break; + end; + + if Result > (CN_MAX_TUINT64 shr 4) then + Break; + if Sign and (Dig <> 0) then + Break; + + Result := Result shl 4 + TUInt64(Dig); + Inc(I); + Empty := False; + end; + end + else + begin + while True do + begin + case Char(S[I]) of + Char('0').. Char('9'): Dig := Ord(S[I]) - Ord('0'); + else + Break; + end; + + if Result > UInt64Div(CN_MAX_TUINT64, 10) then + Break; + if Sign and (Dig <> 0) then + Break; + + Result := Result * 10 + TUInt64(Dig); + Inc(I); + Empty := False; + end; + end; + + if (S[I] <> Char(#0)) or Empty then + Code := I + 1 - FirstIndex + else + Code := 0; +end; + +{$HINTS ON} + +function UInt64ToHex(N: TUInt64): string; +const + Digits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); + + function HC(B: Byte): string; + begin + Result := string(Digits[(B shr 4) and $0F] + Digits[B and $0F]); + end; + +begin + Result := + HC(Byte((N and $FF00000000000000) shr 56)) + + HC(Byte((N and $00FF000000000000) shr 48)) + + HC(Byte((N and $0000FF0000000000) shr 40)) + + HC(Byte((N and $000000FF00000000) shr 32)) + + HC(Byte((N and $00000000FF000000) shr 24)) + + HC(Byte((N and $0000000000FF0000) shr 16)) + + HC(Byte((N and $000000000000FF00) shr 8)) + + HC(Byte((N and $00000000000000FF))); +end; + +function UInt64ToStr(N: TUInt64): string; +begin + Result := Format('%u', [N]); +end; + +function StrToUInt64(const S: string): TUInt64; +{$IFNDEF DELPHIXE6_UP} +var + E: Integer; +{$ENDIF} +begin +{$IFDEF DELPHIXE6_UP} + Result := SysUtils.StrToUInt64(S); // StrToUInt64 only exists under XE6 or above +{$ELSE} + Result := _ValUInt64(S, E); + if E <> 0 then raise EConvertError.CreateResFmt(@SInvalidInteger, [S]); +{$ENDIF} +end; + +function UInt64Compare(A, B: TUInt64): Integer; +{$IFNDEF SUPPORT_UINT64} +var + HiA, HiB, LoA, LoB: Cardinal; +{$ENDIF} +begin +{$IFDEF SUPPORT_UINT64} + if A > B then + Result := 1 + else if A < B then + Result := -1 + else + Result := 0; +{$ELSE} + HiA := (A and $FFFFFFFF00000000) shr 32; + HiB := (B and $FFFFFFFF00000000) shr 32; + if HiA > HiB then + Result := 1 + else if HiA < HiB then + Result := -1 + else + begin + LoA := Cardinal(A and $00000000FFFFFFFF); + LoB := Cardinal(B and $00000000FFFFFFFF); + if LoA > LoB then + Result := 1 + else if LoA < LoB then + Result := -1 + else + Result := 0; + end; +{$ENDIF} +end; + +function UInt64Sqrt(N: TUInt64): TUInt64; +var + Rem, Root: TUInt64; + I: Integer; +begin + Result := 0; + if N = 0 then + Exit; + + if UInt64Compare(N, 4) < 0 then + begin + Result := 1; + Exit; + end; + + Rem := 0; + Root := 0; + + for I := 0 to 31 do + begin + Root := Root shl 1; + Inc(Root); + + Rem := Rem shl 2; + Rem := Rem or (N shr 62); + N := N shl 2; + + if UInt64Compare(Root, Rem) <= 0 then + begin + Rem := Rem - Root; + Inc(Root); + end + else + Dec(Root); + end; + Result := Root shr 1; +end; + +function UInt32IsNegative(N: Cardinal): Boolean; +begin + Result := (N and (1 shl 31)) <> 0; +end; + +function UInt64IsNegative(N: TUInt64): Boolean; +begin +{$IFDEF SUPPORT_UINT64} + Result := (N and (UInt64(1) shl 63)) <> 0; +{$ELSE} + Result := N < 0; +{$ENDIF} +end; + +// UInt64 ijһλ 1λ Index 0 ʼ +procedure UInt64SetBit(var B: TUInt64; Index: Integer); +begin + B := B or (TUInt64(1) shl Index); +end; + +// UInt64 ijһλ 0λ Index 0 ʼ +procedure UInt64ClearBit(var B: TUInt64; Index: Integer); +begin + B := B and not (TUInt64(1) shl Index); +end; + +// UInt64 ĵڼλǷ 10 ʼ +function GetUInt64BitSet(B: TUInt64; Index: Integer): Boolean; +begin + B := B and (TUInt64(1) shl Index); + Result := B <> 0; +end; + +// UInt64 1 ߶λǵڼλλ 0û 1 -1 +function GetUInt64HighBits(B: TUInt64): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 32 = 0 then + begin + Inc(Result, 32); + B := B shl 32; + end; + if B shr 48 = 0 then + begin + Inc(Result, 16); + B := B shl 16; + end; + if B shr 56 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 60 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 62 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 63); // õǰ 0 + Result := 63 - Result; +end; + +// Cardinal 1 ߶λǵڼλλ 0û 1 -1 +function GetUInt32HighBits(B: Cardinal): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 16 = 0 then + begin + Inc(Result, 16); + B := B shl 16; + end; + if B shr 24 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 28 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 30 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 31); // õǰ 0 + Result := 31 - Result; +end; + +function GetUInt16HighBits(B: Word): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 8 = 0 then + begin + Inc(Result, 8); + B := B shl 8; + end; + if B shr 12 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 14 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 15); // õǰ 0 + Result := 15 - Result; +end; + +function GetUInt8HighBits(B: Byte): Integer; +begin + if B = 0 then + begin + Result := -1; + Exit; + end; + + Result := 1; + if B shr 4 = 0 then + begin + Inc(Result, 4); + B := B shl 4; + end; + if B shr 6 = 0 then + begin + Inc(Result, 2); + B := B shl 2; + end; + Result := Result - Integer(B shr 7); // õǰ 0 + Result := 7 - Result; +end; + +// Int64 1 Ͷλǵڼλλ 0û 1 -1 +function GetUInt64LowBits(B: TUInt64): Integer; +var + Y: TUInt64; + N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 63; + Y := B shl 32; + if Y <> 0 then + begin + Dec(N, 32); + B := Y; + end; + Y := B shl 16; + if Y <> 0 then + begin + Dec(N, 16); + B := Y; + end; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 63); +end; + +// Cardinal 1 Ͷλǵڼλλ 0û 1 -1 +function GetUInt32LowBits(B: Cardinal): Integer; +var + Y, N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 31; + Y := B shl 16; + if Y <> 0 then + begin + Dec(N, 16); + B := Y; + end; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 31); +end; + +// Word 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 +function GetUInt16LowBits(B: Word): Integer; +var + Y, N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 15; + Y := B shl 8; + if Y <> 0 then + begin + Dec(N, 8); + B := Y; + end; + Y := B shl 4; + if Y <> 0 then + begin + Dec(N, 4); + B := Y; + end; + Y := B shl 2; + if Y <> 0 then + begin + Dec(N, 2); + B := Y; + end; + B := B shl 1; + Result := N - Integer(B shr 15); +end; + +// Byte 1 Ͷλǵڼλλ 0ͬĩβ 0û 1 -1 +function GetUInt8LowBits(B: Byte): Integer; +var + N: Integer; +begin + Result := -1; + if B = 0 then + Exit; + + N := 7; + if B shr 4 = 0 then + begin + Dec(N, 4); + B := B shl 4; + end; + if B shr 6 = 0 then + begin + Dec(N, 2); + B := B shl 2; + end; + B := B shl 1; + Result := N - Integer(B shr 7); +end; + +// װ Int64 Modֵʱȡģģ +function Int64Mod(M, N: Int64): Int64; +begin + if M > 0 then + Result := M mod N + else + Result := N - ((-M) mod N); +end; + +// жһ 32 λ޷Ƿ 2 +function IsUInt32PowerOf2(N: Cardinal): Boolean; +begin + Result := (N and (N - 1)) = 0; +end; + +// жһ 64 λ޷Ƿ 2 +function IsUInt64PowerOf2(N: TUInt64): Boolean; +begin + Result := (N and (N - 1)) = 0; +end; + +// õһָ 32 λ޷ȵ 2 ݣ򷵻 0 +function GetUInt32PowerOf2GreaterEqual(N: Cardinal): Cardinal; +begin + Result := N - 1; + Result := Result or (Result shr 1); + Result := Result or (Result shr 2); + Result := Result or (Result shr 4); + Result := Result or (Result shr 8); + Result := Result or (Result shr 16); + Inc(Result); +end; + +// õһָ 64 λ޷ 2 ݣ򷵻 0 +function GetUInt64PowerOf2GreaterEqual(N: TUInt64): TUInt64; +begin + Result := N - 1; + Result := Result or (Result shr 1); + Result := Result or (Result shr 2); + Result := Result or (Result shr 4); + Result := Result or (Result shr 8); + Result := Result or (Result shr 16); + Result := Result or (Result shr 32); + Inc(Result); +end; + +// ж 32 λзǷ 32 λз +function IsInt32AddOverflow(A, B: Integer): Boolean; +var + C: Integer; +begin + C := A + B; + Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ + ((A < 0) and (B < 0) and (C > 0)); +end; + +// ж 32 λ޷Ƿ 32 λ޷ +function IsUInt32AddOverflow(A, B: Cardinal): Boolean; +begin + Result := (A + B) < A; // ޷ӣֻҪСһ˵ +end; + +// ж 64 λзǷ 64 λз +function IsInt64AddOverflow(A, B: Int64): Boolean; +var + C: Int64; +begin + C := A + B; + Result := ((A > 0) and (B > 0) and (C < 0)) or // ͬҽ˵ + ((A < 0) and (B < 0) and (C > 0)); +end; + +// ж 64 λ޷Ƿ 64 λ޷ +function IsUInt64AddOverflow(A, B: TUInt64): Boolean; +begin + Result := UInt64Compare(A + B, A) < 0; // ޷ӣֻҪСһ˵ +end; + +function IsUInt64SubOverflowInt32(A: TUInt64; B: TUInt64): Boolean; +var + GT: Boolean; + R: TUInt64; +begin + GT := UInt64Compare(A, B) >= 0; // GT ʾ A >= B + if GT then + begin + R := A - B; + // ж 64 λ޷ŷΧ R Ƿ񳬹 MaxInt32 + Result := UInt64Compare(R, TUInt64(CN_MAX_INT32)) > 0; + end + else + begin + R := B - A; + // ж 64 λзŷΧ -R ǷС MinInt32Ҳж 64 λ޷ R Ƿ񳬹 MinInt32 ޷ʽ + Result := UInt64Compare(R, CN_MIN_INT32_IN_INT64) > 0; + end; +end; + +// 64 λ޷ӣA + B => R 1 λ +procedure UInt64Add(var R: TUInt64; A, B: TUInt64; out Carry: Integer); +begin + R := A + B; + if UInt64Compare(R, A) < 0 then // ޷ӣֻҪСһ˵ + Carry := 1 + else + Carry := 0; +end; + +// 64 λ޷A - B => Rнλ 1 λ +procedure UInt64Sub(var R: TUInt64; A, B: TUInt64; out Carry: Integer); +begin + R := A - B; + if UInt64Compare(R, A) > 0 then // ޷ֻҪڱ˵λ + Carry := 1 + else + Carry := 0; +end; + +// ж 32 λзǷ 32 λз +function IsInt32MulOverflow(A, B: Integer): Boolean; +var + T: Integer; +begin + T := A * B; + Result := (B <> 0) and ((T div B) <> A); +end; + +// ж 32 λ޷Ƿ 32 λ޷ +function IsUInt32MulOverflow(A, B: Cardinal): Boolean; +var + T: TUInt64; +begin + T := TUInt64(A) * TUInt64(B); + Result := (T = Cardinal(T)); +end; + +// ж 32 λ޷Ƿ 64 λзδҲ False ʱR ֱӷؽ +function IsUInt32MulOverflowInt64(A, B: Cardinal; out R: TUInt64): Boolean; +var + T: Int64; +begin + T := Int64(A) * Int64(B); + Result := T < 0; // Int64 ֵ˵ + if not Result then + R := TUInt64(T); +end; + +// ж 64 λзǷ 64 λз +function IsInt64MulOverflow(A, B: Int64): Boolean; +var + T: Int64; +begin + T := A * B; + Result := (B <> 0) and ((T div B) <> A); +end; + +// ָת֧ͣ 32/64 λ +function PointerToInteger(P: Pointer): Integer; +begin +{$IFDEF CPU64BITS} + // ôд Pointer ĵ 32 λ Integer + Result := Integer(P); +{$ELSE} + Result := Integer(P); +{$ENDIF} +end; + +// תָ֧ͣ 32/64 λ +function IntegerToPointer(I: Integer): Pointer; +begin +{$IFDEF CPU64BITS} + // ôд Pointer ĵ 32 λ Integer + Result := Pointer(I); +{$ELSE} + Result := Pointer(I); +{$ENDIF} +end; + +// Int64 Χĺ࣬Ҫ N 0 +function Int64NonNegativeAddMod(A, B, N: Int64): Int64; +begin + if IsInt64AddOverflow(A, B) then // Int64 + begin + if A > 0 then + begin + // A B 0 UInt64 ȡģδ UInt64 ޣע N δ Int64 ȡģС Int64 ޣɸֵ + Result := UInt64NonNegativeAddMod(A, B, N); + end + else + begin + // A B С 0ȡ UInt64 ȡģĺδ UInt64 ޣģٱһ +{$IFDEF SUPPORT_UINT64} + Result := UInt64(N) - UInt64NonNegativeAddMod(-A, -B, N); +{$ELSE} + Result := N - UInt64NonNegativeAddMod(-A, -B, N); +{$ENDIF} + end; + end + else // ֱӼ + Result := Int64NonNegativeMod(A + B, N); +end; + +// UInt64 Χĺ࣬Ҫ N 0 +function UInt64NonNegativeAddMod(A, B, N: TUInt64): TUInt64; +var + C, D: TUInt64; +begin + if IsUInt64AddOverflow(A, B) then // + begin + C := UInt64Mod(A, N); // ͸ģ + D := UInt64Mod(B, N); + if IsUInt64AddOverflow(C, D) then + begin + // ˵ģ󣬸ģûá + // һڵ 2^63N 2^63 + 1 + // = + 2^64 + // mod N = mod N + (2^64 - 1) mod N) + 1 + // N 2^63 + 1 2^64 - 2ǰӲֱӺһģ + Result := UInt64Mod(UInt64Mod(A + B, N) + UInt64Mod(CN_MAX_TUINT64, N) + 1, N); + end + else + Result := UInt64Mod(C + D, N); + end + else + begin + Result := UInt64Mod(A + B, N); + end; +end; + +function Int64NonNegativeMulMod(A, B, N: Int64): Int64; +var + Neg: Boolean; +begin + if N <= 0 then + raise EDivByZero.Create(SDivByZero); + + // ΧСֱ + if not IsInt64MulOverflow(A, B) then + begin + Result := A * B mod N; + if Result < 0 then + Result := Result + N; + Exit; + end; + + // ŵ + Result := 0; + if (A = 0) or (B = 0) then + Exit; + + Neg := False; + if (A < 0) and (B > 0) then + begin + A := -A; + Neg := True; + end + else if (A > 0) and (B < 0) then + begin + B := -B; + Neg := True; + end + else if (A < 0) and (B < 0) then + begin + A := -A; + B := -B; + end; + + // λѭ + while B <> 0 do + begin + if (B and 1) <> 0 then + Result := ((Result mod N) + (A mod N)) mod N; + + A := A shl 1; + if A >= N then + A := A mod N; + + B := B shr 1; + end; + + if Neg then + Result := N - Result; +end; + +function UInt64NonNegativeMulMod(A, B, N: TUInt64): TUInt64; +begin + Result := 0; + if (UInt64Compare(A, CN_MAX_UINT32) <= 0) and (UInt64Compare(B, CN_MAX_UINT32) <= 0) then + begin + Result := UInt64Mod(A * B, N); // 㹻СĻֱӳ˺ģ + end + else + begin + while B <> 0 do + begin + if (B and 1) <> 0 then + Result := UInt64NonNegativeAddMod(Result, A, N); + + A := UInt64NonNegativeAddMod(A, A, N); + // ôͳ㷨 A := A shl 1 N mod NΪ + + B := B shr 1; + end; + end; +end; + +// װķǸຯҲΪʱӸ豣֤ P 0 +function Int64NonNegativeMod(N: Int64; P: Int64): Int64; +begin + if P <= 0 then + raise EDivByZero.Create(SDivByZero); + + Result := N mod P; + if Result < 0 then + Inc(Result, P); +end; + +// Int64 ķǸָ +function Int64NonNegativPower(N: Int64; Exp: Integer): Int64; +var + T: Int64; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + begin + if N <> 0 then + Result := 1 + else + raise EDivByZero.Create(SDivByZero); + end + else if Exp = 1 then + Result := N + else + begin + Result := 1; + T := N; + + while Exp > 0 do + begin + if (Exp and 1) <> 0 then + Result := Result * T; + + Exp := Exp shr 1; + T := T * T; + end; + end; +end; + +function Int64NonNegativeRoot(N: Int64; Exp: Integer): Int64; +var + I: Integer; + X: Int64; + X0, X1: Extended; +begin + if (Exp < 0) or (N < 0) then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + raise EDivByZero.Create(SDivByZero) + else if (N = 0) or (N = 1) then + Result := N + else if Exp = 2 then + Result := UInt64Sqrt(N) + else + begin + // ţٵ + I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ + I := (I div Exp) + 1; + X := 1 shl I; // õһϴ X0 ֵΪʼֵ + + X0 := X; + X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); + + while True do + begin + if (Trunc(X0) = Trunc(X1)) and (Abs(X0 - X1) < 0.001) then + begin + Result := Trunc(X1); // Trunc ֻ֧ Int64˻ + Exit; + end; + + X0 := X1; + X1 := X0 - (Power(X0, Exp) - N) / (Exp * Power(X0, Exp - 1)); + end; + end; +end; + +function UInt64NonNegativPower(N: TUInt64; Exp: Integer): TUInt64; +var + T, RL, RH: TUInt64; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + begin + if N <> 0 then + Result := 1 + else + raise EDivByZero.Create(SDivByZero); + end + else if Exp = 1 then + Result := N + else + begin + Result := 1; + T := N; + + while Exp > 0 do + begin + if (Exp and 1) <> 0 then + begin + UInt64MulUInt64(Result, T, RL, RH); + Result := RL; + end; + + Exp := Exp shr 1; + UInt64MulUInt64(T, T, RL, RH); + T := RL; + end; + end; +end; + +function UInt64NonNegativeRoot(N: TUInt64; Exp: Integer): TUInt64; +var + I: Integer; + X: TUInt64; + XN, X0, X1: Extended; +begin + if Exp < 0 then + raise ERangeError.Create(SRangeError) + else if Exp = 0 then + raise EDivByZero.Create(SDivByZero) + else if (N = 0) or (N = 1) then + Result := N + else if Exp = 2 then + Result := UInt64Sqrt(N) + else + begin + // ţٵ + I := GetUInt64HighBits(N) + 1; // õԼ Log2 N ֵ + I := (I div Exp) + 1; + X := 1 shl I; // õһϴ X0 ֵΪʼֵ + + X0 := UInt64ToExtended(X); + XN := UInt64ToExtended(N); + X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); + + while True do + begin + if (ExtendedToUInt64(X0) = ExtendedToUInt64(X1)) and (Abs(X0 - X1) < 0.001) then + begin + Result := ExtendedToUInt64(X1); + Exit; + end; + + X0 := X1; + X1 := X0 - (Power(X0, Exp) - XN) / (Exp * Power(X0, Exp - 1)); + end; + end; +end; + +function IsUInt128BitSet(Lo, Hi: TUInt64; N: Integer): Boolean; +begin + if N < 64 then + Result := (Lo and (TUInt64(1) shl N)) <> 0 + else + begin + Dec(N, 64); + Result := (Hi and (TUInt64(1) shl N)) <> 0; + end; +end; + +procedure SetUInt128Bit(var Lo, Hi: TUInt64; N: Integer); +begin + if N < 64 then + Lo := Lo or (TUInt64(1) shl N) + else + begin + Dec(N, 64); + Hi := Hi or (TUInt64(1) shl N); + end; +end; + +procedure ClearUInt128Bit(var Lo, Hi: TUInt64; N: Integer); +begin + if N < 64 then + Lo := Lo and not (TUInt64(1) shl N) + else + begin + Dec(N, 64); + Hi := Hi and not (TUInt64(1) shl N); + end; +end; + +function UnsignedAddWithLimitRadix(A, B, C: Cardinal; var R: Cardinal; + L, H: Cardinal): Cardinal; +begin + R := A + B + C; + if R > H then // нλ + begin + A := H - L + 1; // õ + B := R - L; // õ L ֵ + + Result := B div A; // Ƶĵڼͽ + R := L + (B mod A); // ȥƺ + end + else + Result := 0; +end; + +procedure InternalQuickSort(Mem: Pointer; L, R: Integer; ElementByteSize: Integer; + CompareProc: TCnMemSortCompareProc); +var + I, J, P: Integer; +begin + repeat + I := L; + J := R; + P := (L + R) shr 1; + repeat + while CompareProc(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), + Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) < 0 do + Inc(I); + while CompareProc(Pointer(TCnNativeInt(Mem) + J * ElementByteSize), + Pointer(TCnNativeInt(Mem) + P * ElementByteSize), ElementByteSize) > 0 do + Dec(J); + + if I <= J then + begin + MemorySwap(Pointer(TCnNativeInt(Mem) + I * ElementByteSize), + Pointer(TCnNativeInt(Mem) + J * ElementByteSize), ElementByteSize); + + if P = I then + P := J + else if P = J then + P := I; + Inc(I); + Dec(J); + end; + until I > J; + + if L < J then + InternalQuickSort(Mem, L, J, ElementByteSize, CompareProc); + L := I; + until I >= R; +end; + +function DefaultCompareProc(P1, P2: Pointer; ElementByteSize: Integer): Integer; +begin + Result := MemoryCompare(P1, P2, ElementByteSize); +end; + +procedure MemoryQuickSort(Mem: Pointer; ElementByteSize: Integer; + ElementCount: Integer; CompareProc: TCnMemSortCompareProc); +begin + if (Mem <> nil) and (ElementCount > 0) and (ElementCount > 0) then + begin + if Assigned(CompareProc) then + InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, CompareProc) + else + InternalQuickSort(Mem, 0, ElementCount - 1, ElementByteSize, DefaultCompareProc); + end; +end; + +{$IFDEF COMPILER5} + +function BoolToStr(Value: Boolean; UseBoolStrs: Boolean): string; +begin + if UseBoolStrs then + begin + if Value then + Result := 'True' + else + Result := 'False'; + end + else + begin + if Value then + Result := '-1' + else + Result := '0'; + end; +end; + +{$ENDIF} + +// =========================== ѭλ ==================================== + +function RotateLeft16(A: Word; N: Integer): Word; +begin + Result := (A shl N) or (A shr (16 - N)); +end; + +function RotateRight16(A: Word; N: Integer): Word; +begin + Result := (A shr N) or (A shl (16 - N)); +end; + +function RotateLeft32(A: Cardinal; N: Integer): Cardinal; +begin + Result := (A shl N) or (A shr (32 - N)); +end; + +function RotateRight32(A: Cardinal; N: Integer): Cardinal; +begin + Result := (A shr N) or (A shl (32 - N)); +end; + +function RotateLeft64(A: TUInt64; N: Integer): TUInt64; +begin + Result := (A shl N) or (A shr (64 - N)); +end; +function RotateRight64(A: TUInt64; N: Integer): TUInt64; +begin + Result := (A shr N) or (A shl (64 - N)); +end; + +initialization + FByteOrderIsBigEndian := CurrentByteOrderIsBigEndian; + +end. diff --git a/CnPack/Crypto/CnPemUtils.dcu b/CnPack/Crypto/CnPemUtils.dcu new file mode 100644 index 0000000000000000000000000000000000000000..b14a181ea709064b3476fff66071bca6173099f8 GIT binary patch literal 16968 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 HV0HfoxNO-h literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnPemUtils.pas b/CnPack/Crypto/CnPemUtils.pas new file mode 100644 index 0000000..f4d5719 --- /dev/null +++ b/CnPack/Crypto/CnPemUtils.pas @@ -0,0 +1,1219 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnPemUtils; +{* |
+================================================================================
+* ƣ
+* ԪƣPEM ʽ뵥Ԫ
+* ԪߣCnPack 
+*     עԪʵ PEM ʽĶȡ뱣棬ӽܻơ
+*           Ҳʵ PKCS1/PKCS5/PKCS7/ISO10126 ȶ봦ơ
+*           ע֧ PKCS12 淶֤鼰Կװʽ
+* ƽ̨WinXP + Delphi 5.0
+* ݲԣδ
+*   õԪ豾ػ
+* ޸ļ¼2024.05.27 V1.6
+*                ISO10126 Ĵ
+*           2023.12.14 V1.5
+*                SaveMemoryToPemStream δ
+*           2022.03.09 V1.4
+*                PKCS5 Ĵ
+*           2021.05.14 V1.3
+*               ĸ PKCS7 Ĵ
+*           2020.03.27 V1.2
+*               ģ Openssl ʵ PEM ļд룬ֲֻּ֧㷨
+*               Ŀǰд des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
+*           2020.03.23 V1.1
+*               ģ Openssl ʵ PEM ļܶȡֲֻּ֧㷨
+*               Ŀǰȡ des/3des/aes128/192/256 PKCS7 룬 Openssl 1.0.2g
+*           2020.03.18 V1.0
+*               Ԫ CnRSA ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes, CnNative, CnRandom, CnKDF, CnBase64, CnAES, CnDES; + +const + CN_PKCS1_BLOCK_TYPE_PRIVATE_00 = 00; + {* PKCS1 ʱĿֵֶһĬӦ RSA ˽Կܳ} + + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF = 01; + {* PKCS1 ʱĿֵֶĬӦ RSA ˽Կǩ} + + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM = 02; + {* PKCS1 ʱĿֵֶĬӦ RSA ĹԿܳ} + +type + TCnKeyHashMethod = (ckhMd5, ckhSha256); + {* PEM ʽֵ֧Ӵ} + + TCnKeyEncryptMethod = (ckeNone, ckeDES, cke3DES, ckeAES128, ckeAES192, ckeAES256); + {* PEM ʽֵ֧ļ} + +// ======================= PEM ļдּ֧ӽ ======================== + +function LoadPemFileToMemory(const FileName: string; const ExpectHead: string; + const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; + KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; +{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 + + + const FileName: string - ļ + const ExpectHead: string - ͷ + const ExpectTail: string - β + MemoryStream: TMemoryStream - ڴ + const Password: string - ļܣڴṩ + KeyHashMethod: TCnKeyHashMethod - ļʹõӴ + + ֵBoolean - ضǷɹ +} + +function LoadPemStreamToMemory(Stream: TStream; const ExpectHead: string; + const ExpectTail: string; MemoryStream: TMemoryStream; const Password: string = ''; + KeyHashMethod: TCnKeyHashMethod = ckhMd5): Boolean; +{* PEM ʽļָ֤ͷβʵݲܽ Base64 롣 + + + Stream: TStream - + const ExpectHead: string - ͷ + const ExpectTail: string - β + MemoryStream: TMemoryStream - ڴ + const Password: string - ܣڴṩ + KeyHashMethod: TCnKeyHashMethod - ʹõӴ + + ֵBoolean - ضǷɹ +} + +function SaveMemoryToPemFile(const FileName: string; const Head: string; const Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; + KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; +{* Stream ݽ Base64 ܷвļͷβдļAppend Ϊ True ʱʾ׷ӡ + + + const FileName: string - дļ + const Head: string - дͷ + const Tail: string - дβ + MemoryStream: TMemoryStream - д + KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ + KeyHashMethod: TCnKeyHashMethod - Ӵ + const Password: string - 룬򴫿 + Append: Boolean - Ƿ׷ӵķʽд + + ֵBoolean - Ƿдɹ +} + +function SaveMemoryToPemStream(Stream: TStream; const Head: string; const Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod = ckeNone; + KeyHashMethod: TCnKeyHashMethod = ckhMd5; const Password: string = ''; Append: Boolean = False): Boolean; +{* Stream ݽ Base64 ܷвͷβдAppend Ϊ True ʱʾ׷ӡ + + + Stream: TStream - д + const Head: string - дͷ + const Tail: string - дβ + MemoryStream: TMemoryStream - д + KeyEncryptMethod: TCnKeyEncryptMethod - üͣĬϲ + KeyHashMethod: TCnKeyHashMethod - ӴͣĬϲӴ + const Password: string - 룬򴫿 + Append: Boolean - Ƿ׷ӵķʽд + + ֵBoolean - Ƿдɹ +} + +// ===================== PKCS1 / PKCS7 Padding 봦 ==================== + +function AddPKCS1Padding(PaddingType: Integer; BlockSize: Integer; Data: Pointer; + DataByteLen: Integer; OutStream: TStream): Boolean; +{* ݿ鲹д Stream Уسɹڲô롣 + PaddingType ȡ 012BlockLen ֽ 128 ȡʽ + EB = 00 || BT || PS || 00 || D + 00 ǰ涨ֽڣBT 1 ֽڵ PaddingType0 1 2 ֱ 00 FF + PS Ķֽݣ 00 ǹ涨Ľβֽڡ + + + PaddingType: Integer - ͣȡ 0 1 2 + BlockSize: Integer - ֽڳ + Data: Pointer - ݿĵַ + DataByteLen: Integer - ݿֽڳ + OutStream: TStream - + + ֵBoolean - ضǷӳɹ +} + +function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; + out OutByteLen: Integer): Boolean; +{* ȥݿ PKCS1 PaddingسɹOutBuf ָĿóб֤ + ɹOutLen ԭݳȡ + + + InData: Pointer - ȥݿĵַ + InDataByteLen: Integer - ȥݿֽڳ + OutBuf: Pointer - ȥݵ䳤ȱ㹻 + out OutByteLen: Integer - ȥݳ + + ֵBoolean - ضǷȥɹ +} + +function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +{* ԭʼ鳤ȼ PKCS7 ijȡ + + + OrignalByteLen: Integer - ԭʼֽڳ + BlockSize: Integer - PKCS7 ֽڳ + + ֵInteger - PKCS7 ֽڳ +} + +procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); +{* ĩβ PKCS7 涨䡰ݡ + + + Stream: TMemoryStream - ڴݣݽ׷дβ + BlockSize: Integer - PKCS7 ֽڳ + + ֵޣ +} + +procedure RemovePKCS7Padding(Stream: TMemoryStream); +{* ȥ PKCS7 涨ĩβ䡰ݡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ} + +function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +{* ַĩβ PKCS7 涨䡰ݡ + + + const Str: AnsiString - ַ + BlockSize: Integer - PKCS7 ֽڳ + + ֵAnsiString - ضַ +} + +function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; +{* ȥ PKCS7 涨ַĩβ䡰ݡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); +{* ֽĩβ PKCS7 涨䡰ݡ + + + var Data: TBytes - ֽ飬ݽ׷β + BlockSize: Integer - PKCS7 ֽڳ + + ֵޣ +} + +procedure BytesRemovePKCS7Padding(var Data: TBytes); +{* ȥ PKCS7 涨ֽĩβ䡰ݡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +procedure AddPKCS5Padding(Stream: TMemoryStream); +{* ĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + Stream: TMemoryStream - ڴݽ׷β + + ֵޣ +} + +procedure RemovePKCS5Padding(Stream: TMemoryStream); +{* ȥ PKCS7 涨ĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ +} + +function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; +{* ַĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + const Str: AnsiString - ַ + + ֵAnsiString - ضַ +} + +function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; +{* ȥ PKCS5 涨ַĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddPKCS5Padding(var Data: TBytes); +{* ֽĩβ PKCS5 涨䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + var Data: TBytes - ֽ飬ݽ׷β + + ֵޣ +} + +procedure BytesRemovePKCS5Padding(var Data: TBytes); +{* ȥ PKCS7 涨ֽĩβ䡰ݣѭ PKCS7 淶С̶Ϊ 8 ֽڡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +{* ԭʼ鳤ȼ ISO10126Padding ijȡ + + + OrignalByteLen: Integer - ԭʼֽڳ + BlockSize: Integer - ISO10126 ֽڳ + + ֵInteger - PKCS7 ֽڳ +} + +procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); +{* ĩβ ISO10126Padding 涨䡰ͼݡ + + + Stream: TMemoryStream - ڴݽ׷β + BlockSize: Integer - ISO10126 ֽڳ + + ֵޣ +} + +procedure RemoveISO10126Padding(Stream: TMemoryStream); +{* ȥ ISO10126Padding 涨ĩβ䡰ͼݡ + + + Stream: TMemoryStream - ȥڴ + + ֵޣ +} + +function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +{* ַĩβ ISO10126Padding 涨䡰ͼݡ + + + const Str: AnsiString - ַ + BlockSize: Integer - ISO10126 ֽڴС + + ֵAnsiString - ضַ +} + +function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; +{* ȥ ISO10126Padding 涨ַĩβ䡰ͼݡ + + + const Str: AnsiString - ȥַ + + ֵAnsiString - ȥַ +} + +procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); +{* ֽĩβ ISO10126Padding 涨䡰ͼݡ + + + var Data: TBytes - ֽ飬ݽ׷β + BlockSize: Integer - ISO10126 ֽڳ + + ֵޣ +} + +procedure BytesRemoveISO10126Padding(var Data: TBytes); +{* ȥ ISO10126Padding 涨ֽĩβ䡰ͼݡ + + + var Data: TBytes - ȥֽ + + ֵޣ +} + +implementation + +const + PKCS1_PADDING_SIZE = 11; // һǰ 00һֽڡ 8 ֽ䣬һ 00 β + PKCS5_BLOCK_SIZE = 8; + + ENC_HEAD_PROCTYPE = 'Proc-Type:'; + ENC_HEAD_PROCTYPE_NUM = '4'; + ENC_HEAD_ENCRYPTED = 'ENCRYPTED'; + ENC_HEAD_DEK = 'DEK-Info:'; + + ENC_TYPE_AES128 = 'AES-128'; + ENC_TYPE_AES192 = 'AES-192'; + ENC_TYPE_AES256 = 'AES-256'; + ENC_TYPE_DES = 'DES'; + ENC_TYPE_3DES = 'DES-EDE3'; + + ENC_BLOCK_CBC = 'CBC'; + + ENC_TYPE_STRS: array[TCnKeyEncryptMethod] of string = + ('', ENC_TYPE_DES, ENC_TYPE_3DES, ENC_TYPE_AES128, ENC_TYPE_AES192, ENC_TYPE_AES256); + + ENC_TYPE_BLOCK_SIZE: array[TCnKeyEncryptMethod] of Byte = + (0, 8, 8, 16, 16, 16); + +function Min(A, B: Integer): Integer; +begin + if A < B then + Result := A + else + Result := B; +end; + +function AddPKCS1Padding(PaddingType, BlockSize: Integer; Data: Pointer; + DataByteLen: Integer; OutStream: TStream): Boolean; +var + I: Integer; + B, F: Byte; +begin + Result := False; + if (Data = nil) or (DataByteLen <= 0) then + Exit; + + // + if DataByteLen > BlockSize - PKCS1_PADDING_SIZE then + Exit; + + B := 0; + OutStream.Write(B, 1); // дǰֽ 00 + B := PaddingType; + F := BlockSize - DataByteLen - 3; // 3 ʾһǰ 00һֽڡһ 00 β + + OutStream.Write(B, 1); + case PaddingType of + CN_PKCS1_BLOCK_TYPE_PRIVATE_00: + begin + B := 0; + for I := 1 to F do + OutStream.Write(B, 1); + end; + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF: + begin + B := $FF; + for I := 1 to F do + OutStream.Write(B, 1); + end; + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: + begin + Randomize; + for I := 1 to F do + begin + B := Trunc(Random(255)); + if B = 0 then + Inc(B); + OutStream.Write(B, 1); + end; + end; + else + Exit; + end; + + B := 0; + OutStream.Write(B, 1); + OutStream.Write(Data^, DataByteLen); + Result := True; +end; + +function RemovePKCS1Padding(InData: Pointer; InDataByteLen: Integer; OutBuf: Pointer; + out OutByteLen: Integer): Boolean; +var + P: PAnsiChar; + I, J, Start: Integer; +begin + Result := False; + OutByteLen := 0; + I := 0; + + P := PAnsiChar(InData); + while P[I] = #0 do // ַһ #0Ѿȥ + Inc(I); + + if I >= InDataByteLen then + Exit; + + Start := 0; + case Ord(P[I]) of + CN_PKCS1_BLOCK_TYPE_PRIVATE_00: + begin + // P[I + 1] ʼѰҷ 00 + J := I + 1; + while J < InDataByteLen do + begin + if P[J] <> #0 then + begin + Start := J; + Break; + end; + Inc(J); + end; + end; + CN_PKCS1_BLOCK_TYPE_PRIVATE_FF, + CN_PKCS1_BLOCK_TYPE_PUBLIC_RANDOM: + begin + // P[I + 1] ʼѰҵһ 00 ı + J := I + 1; + while J < InDataByteLen do + begin + if P[J] = #0 then + begin + Start := J; + Break; + end; + Inc(J); + end; + + if Start <> 0 then + Inc(Start); + end; + end; + + if Start > 0 then + begin + Move(P[Start], OutBuf^, InDataByteLen - Start); + OutByteLen := InDataByteLen - Start; + Result := True; + end; +end; + +function GetPKCS7PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +var + R: Byte; +begin + R := OrignalByteLen mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + Result := OrignalByteLen + R; +end; + +procedure AddPKCS7Padding(Stream: TMemoryStream; BlockSize: Integer); +var + R: Byte; + Buf: array[0..255] of Byte; +begin + R := Stream.Size mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + FillChar(Buf[0], R, R); + Stream.Position := Stream.Size; + Stream.Write(Buf[0], R); +end; + +procedure RemovePKCS7Padding(Stream: TMemoryStream); +var + L: Byte; + Len: Cardinal; + Mem: Pointer; +begin + // ȥ Stream ĩβ 9 9 Padding + if Stream.Size > 1 then + begin + Stream.Position := Stream.Size - 1; + Stream.Read(L, 1); + + if Stream.Size - L < 0 then // ߴ粻ף + Exit; + + Len := Stream.Size - L; + Mem := GetMemory(Len); + if Mem <> nil then + begin + Move(Stream.Memory^, Mem^, Len); + Stream.Clear; + Stream.Write(Mem^, Len); + FreeMemory(Mem); + end; + end; +end; + +function StrAddPKCS7Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +var + I, L: Integer; + R: Byte; +begin + L := Length(Str); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Result, L + R); + if L > 0 then + Move(Str[1], Result[1], L); + + for I := 1 to R do + Result[L + I] := AnsiChar(R); +end; + +function StrRemovePKCS7Padding(const Str: AnsiString): AnsiString; +var + L: Integer; + V: Byte; +begin + Result := Str; + if Result = '' then + Exit; + + L := Length(Result); + V := Ord(Result[L]); // ĩǼʾ˼ + + if V <= L then + Delete(Result, L - V + 1, V); +end; + +procedure AddPKCS5Padding(Stream: TMemoryStream); +begin + AddPKCS7Padding(Stream, PKCS5_BLOCK_SIZE); +end; + +procedure RemovePKCS5Padding(Stream: TMemoryStream); +begin + RemovePKCS7Padding(Stream); +end; + +function StrAddPKCS5Padding(const Str: AnsiString): AnsiString; +begin + Result := StrAddPKCS7Padding(Str, PKCS5_BLOCK_SIZE); +end; + +function StrRemovePKCS5Padding(const Str: AnsiString): AnsiString; +begin + Result := StrRemovePKCS7Padding(Str); +end; + +procedure BytesAddPKCS7Padding(var Data: TBytes; BlockSize: Integer); +var + R: Byte; + L, I: Integer; +begin + L := Length(Data); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Data, L + R); + for I := 0 to R - 1 do + Data[L + I] := R; +end; + +procedure BytesRemovePKCS7Padding(var Data: TBytes); +var + L: Integer; + V: Byte; +begin + L := Length(Data); + if L = 0 then + Exit; + + V := Ord(Data[L - 1]); // ĩǼʾ˼ֽ + + if V <= L then + SetLength(Data, L - V); +end; + +procedure BytesAddPKCS5Padding(var Data: TBytes); +begin + BytesAddPKCS7Padding(Data, PKCS5_BLOCK_SIZE); +end; + +procedure BytesRemovePKCS5Padding(var Data: TBytes); +begin + BytesRemovePKCS7Padding(Data); +end; + +function GetISO10126PaddingByteLength(OrignalByteLen: Integer; BlockSize: Integer): Integer; +begin + Result := GetPKCS7PaddingByteLength(OrignalByteLen, BlockSize); // Ϊֱͬӵ +end; + +procedure AddISO10126Padding(Stream: TMemoryStream; BlockSize: Integer); +var + R: Byte; + Buf: array[0..255] of Byte; +begin + R := Stream.Size mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + FillChar(Buf[0], R, 0); + Buf[R - 1] := R; + Stream.Position := Stream.Size; + Stream.Write(Buf[0], R); +end; + +procedure RemoveISO10126Padding(Stream: TMemoryStream); +begin + RemovePKCS7Padding(Stream); // Ϊֱͬӵ +end; + +function StrAddISO10126Padding(const Str: AnsiString; BlockSize: Integer): AnsiString; +var + I, L: Integer; + R: Byte; +begin + L := Length(Str); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Result, L + R); + if L > 0 then + Move(Str[1], Result[1], L); + + if R > 1 then + begin + for I := 1 to R - 1 do + Result[L + I] := #0; + end; + Result[L + R] := AnsiChar(R); +end; + +function StrRemoveISO10126Padding(const Str: AnsiString): AnsiString; +begin + Result := StrRemovePKCS7Padding(Str); // Ϊֱͬӵ +end; + +procedure BytesAddISO10126Padding(var Data: TBytes; BlockSize: Integer); +var + R: Byte; + L, I: Integer; +begin + L := Length(Data); + R := L mod BlockSize; + R := BlockSize - R; + if R = 0 then + R := R + BlockSize; + + SetLength(Data, L + R); + if R > 1 then + begin + for I := 0 to R - 2 do + Data[L + I] := 0; + end; + Data[L - 1 + R] := R; +end; + +procedure BytesRemoveISO10126Padding(var Data: TBytes); +begin + BytesRemovePKCS7Padding(Data); // Ϊֱͬӵ +end; + +function EncryptPemStream(KeyHash: TCnKeyHashMethod; KeyEncrypt: TCnKeyEncryptMethod; + Stream: TStream; const Password: string; out EncryptedHead: string): Boolean; +const + CRLF = #13#10; +var + ES: TMemoryStream; + Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ + IvStr: AnsiString; + HexIv: string; + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + AesIv: TCnAESBuffer; + DesKey: TCnDESKey; + Des3Key: TCn3DESKey; + DesIv: TCnDESIv; +begin + Result := False; + + // + if (KeyEncrypt = ckeNone) or (Password = '') then + Exit; + + // Iv + SetLength(IvStr, ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); + CnRandomFillBytes(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt]); + HexIv := DataToHex(@(IvStr[1]), ENC_TYPE_BLOCK_SIZE[KeyEncrypt], True); // Ҫд + + EncryptedHead := ENC_HEAD_PROCTYPE + ' ' + ENC_HEAD_PROCTYPE_NUM + ',' + ENC_HEAD_ENCRYPTED + CRLF; + EncryptedHead := EncryptedHead + ENC_HEAD_DEK + ' ' + ENC_TYPE_STRS[KeyEncrypt] + + '-' + ENC_BLOCK_CBC + ',' + HexIv + CRLF; + + ES := TMemoryStream.Create; + Stream.Position := 0; + + try + if KeyHash = ckhMd5 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then + Exit; + end + else if KeyHash = ckhSha256 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then + Exit; + end + else + Exit; + + case KeyEncrypt of + ckeDES: + begin + Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); + Move(IvStr[1], DesIv[0], SizeOf(TCnDESIv)); + + DESEncryptStreamCBC(Stream, Stream.Size, DesKey, DesIv, ES); + Result := True; + end; + cke3DES: + begin + Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); + Move(IvStr[1], DesIv[0], SizeOf(TCn3DESIv)); + + TripleDESEncryptStreamCBC(Stream, Stream.Size, Des3Key, DesIv, ES); + Result := True; + end; + ckeAES128: + begin + Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES128StreamCBC(Stream, Stream.Size, AESKey128, AesIv, ES); + Result := True; + end; + ckeAES192: + begin + Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES192StreamCBC(Stream, Stream.Size, AESKey192, AesIv, ES); + Result := True; + end; + ckeAES256: + begin + Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); + Move(IvStr[1], AesIv[0], SizeOf(TCnAESBuffer)); + + EncryptAES256StreamCBC(Stream, Stream.Size, AESKey256, AesIv, ES); + Result := True; + end; + end; + finally + if ES.Size > 0 then + begin + // ES д Stream + Stream.Size := 0; + Stream.Position := 0; + ES.SaveToStream(Stream); + Stream.Position := 0; + end; + ES.Free; + end; +end; + +// ü㷨㡢ʼ⿪ Base64 Sд Stream +function DecryptPemString(const S, M1, M2, HexIv, Password: string; Stream: TMemoryStream; + KeyHash: TCnKeyHashMethod): Boolean; +var + DS: TMemoryStream; + Keys: array[0..31] of Byte; //  Key Ҳֻ 32 ֽ + AESKey128: TCnAESKey128; + AESKey192: TCnAESKey192; + AESKey256: TCnAESKey256; + IvStr: AnsiString; + AesIv: TCnAESBuffer; + DesKey: TCnDESKey; + Des3Key: TCn3DESKey; + DesIv: TCnDESIv; +begin + Result := False; + DS := nil; + + if (M1 = '') or (M2 = '') or (HexIv = '') or (Password = '') then + Exit; + + try + DS := TMemoryStream.Create; + if ECN_BASE64_OK <> Base64Decode(AnsiString(S), DS, False) then + Exit; + + DS.Position := 0; + SetLength(IvStr, HexToData(HexIv)); + if Length(IvStr) > 0 then + HexToData(HexIv, @IvStr[1]); + + // Salt Լ Hash 㷨ӽܵ Key + FillChar(Keys[0], SizeOf(Keys), 0); + if KeyHash = ckhMd5 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys)) then + Exit; + end + else if KeyHash = ckhSha256 then + begin + if not CnGetDeriveKey(AnsiString(Password), IvStr, @Keys[0], SizeOf(Keys), ckdSha256) then + Exit; + end + else + Exit; + + // DS ģҪ⵽ Stream + if (M1 = ENC_TYPE_AES256) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-256-CBC ܵ + Move(Keys[0], AESKey256[0], SizeOf(TCnAESKey256)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES256StreamCBC(DS, DS.Size, AESKey256, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_AES192) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-192-CBC ܵ + Move(Keys[0], AESKey192[0], SizeOf(TCnAESKey192)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES192StreamCBC(DS, DS.Size, AESKey192, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_AES128) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ AES-128-CBC ܵģ D5 òƿ Bug ³ AV + Move(Keys[0], AESKey128[0], SizeOf(TCnAESKey128)); + Move(IvStr[1], AesIv[0], Min(SizeOf(TCnAESBuffer), Length(IvStr))); + + DecryptAES128StreamCBC(DS, DS.Size, AESKey128, AesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_DES) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ DES-CBC ܵ + Move(Keys[0], DesKey[0], SizeOf(TCnDESKey)); + Move(IvStr[1], DesIv[0], Min(SizeOf(TCnDESIv), Length(IvStr))); + + DESDecryptStreamCBC(DS, DS.Size, DesKey, DesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end + else if (M1 = ENC_TYPE_3DES) and (M2 = ENC_BLOCK_CBC) then + begin + // ⿪ 3DES-CBC ܵ + Move(Keys[0], Des3Key[0], SizeOf(TCn3DESKey)); + Move(IvStr[1], DesIv[0], Min(SizeOf(TCn3DESIv), Length(IvStr))); + + TripleDESDecryptStreamCBC(DS, DS.Size, Des3Key, DesIv, Stream); + RemovePKCS7Padding(Stream); + Result := True; + end; + finally + DS.Free; + end; +end; + +function LoadPemStreamToMemory(Stream: TStream; const ExpectHead, ExpectTail: string; + MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; +var + I, J, HeadIndex, TailIndex: Integer; + S, L1, L2, M1, M2, M3: string; + Sl: TStringList; +begin + Result := False; + + if (Stream <> nil) and (Stream.Size > 0) and (ExpectHead <> '') and (ExpectTail <> '') then + begin + Sl := TStringList.Create; + try + Sl.LoadFromStream(Stream); + if Sl.Count > 2 then + begin + HeadIndex := -1; + for I := 0 to Sl.Count - 1 do + begin + if Trim(Sl[I]) = ExpectHead then + begin + HeadIndex := I; + Break; + end; + end; + + if HeadIndex < 0 then + Exit; + + if HeadIndex > 0 then + for I := 0 to HeadIndex - 1 do + Sl.Delete(0); + + // ҵͷˣβ + + TailIndex := -1; + for I := 0 to Sl.Count - 1 do + begin + if Trim(Sl[I]) = ExpectTail then + begin + TailIndex := I; + Break; + end; + end; + + if TailIndex > 0 then // ҵβͣɾβͺĶ + begin + if TailIndex < Sl.Count - 1 then + for I := Sl.Count - 1 downto TailIndex + 1 do + Sl.Delete(Sl.Count - 1); + end + else + Exit; + + if Sl.Count < 2 then // ûݣ˳ + Exit; + + // ͷβ֤ͨǰжǷ + L1 := Sl[1]; + if Pos(ENC_HEAD_PROCTYPE, L1) = 1 then // Ǽܵ + begin + Delete(L1, 1, Length(ENC_HEAD_PROCTYPE)); + I := Pos(',', L1); + if I <= 1 then + Exit; + + if Trim(Copy(L1, 1, I - 1)) <> ENC_HEAD_PROCTYPE_NUM then + Exit; + + if Trim(Copy(L1, I + 1, MaxInt)) <> ENC_HEAD_ENCRYPTED then + Exit; + + // ProcType: 4,ENCRYPTED жͨ + + L2 := Sl[2]; + if Pos(ENC_HEAD_DEK, L2) <> 1 then + Exit; + + Delete(L2, 1, Length(ENC_HEAD_DEK)); + I := Pos(',', L2); + if I <= 1 then + Exit; + + M1 := Trim(Copy(L2, 1, I - 1)); // õ AES256-CBC + M3 := UpperCase(Trim(Copy(L2, I + 1, MaxInt))); // õʱʹõijʼ + I := Pos('-', M1); + if I <= 1 then + Exit; + J := Pos('-', Copy(M1, I + 1, MaxInt)); + if J > 0 then + I := I + J; // AES-256-CBC + + M2 := UpperCase(Trim(Copy(M1, I + 1, MaxInt))); // õģʽ ECB CBC + M1 := UpperCase(Trim(Copy(M1, 1, I - 1))); // õ㷨 DES AES + + // ͷβȫɾ + Sl.Delete(Sl.Count - 1); + Sl.Delete(0); + Sl.Delete(0); + Sl.Delete(0); + + S := ''; + for I := 0 to Sl.Count - 1 do + S := S + Sl[I]; + + S := Trim(S); + + Result := DecryptPemString(S, M1, M2, M3, Password, MemoryStream, KeyHashMethod); + end + else // δܵģƴճ Base64 + begin + Sl.Delete(Sl.Count - 1); + Sl.Delete(0); + S := ''; + for I := 0 to Sl.Count - 1 do + S := S + Sl[I]; + + S := Trim(S); + + // To De Base64 S + MemoryStream.Clear; +{$IFDEF UNICODE} + Result := (ECN_BASE64_OK = Base64Decode(AnsiString(S), MemoryStream, False)); +{$ELSE} + Result := (ECN_BASE64_OK = Base64Decode(S, MemoryStream, False)); +{$ENDIF} + end; + end; + finally + Sl.Free; + end; + end; +end; + +function LoadPemFileToMemory(const FileName, ExpectHead, ExpectTail: string; + MemoryStream: TMemoryStream; const Password: string; KeyHashMethod: TCnKeyHashMethod): Boolean; +var + Stream: TStream; +begin + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + Result := LoadPemStreamToMemory(Stream, ExpectHead, ExpectTail, MemoryStream, Password, KeyHashMethod); + finally + Stream.Free; + end; +end; + +procedure SplitStringToList(const S: string; List: TStrings); +const + LINE_WIDTH = 64; +var + C, R: string; +begin + if List = nil then + Exit; + + List.Clear; + if S <> '' then + begin + R := S; + while R <> '' do + begin + C := Copy(R, 1, LINE_WIDTH); + Delete(R, 1, LINE_WIDTH); + List.Add(C); + end; + end; +end; + +function SaveMemoryToPemFile(const FileName, Head, Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; + KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; +var + S, EH: string; + List, Sl: TStringList; +begin + Result := False; + if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then + begin + MemoryStream.Position := 0; + + if (KeyEncryptMethod <> ckeNone) and (Password <> '') then + begin + // MemoryStream + AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); + + // ټ + if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then + Exit; + end; + + if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then + begin + List := TStringList.Create; + try + SplitStringToList(S, List); + + List.Insert(0, Head); // ͨͷ + if EH <> '' then // ͷ + List.Insert(1, EH); + List.Add(Tail); // ͨβ + + if Append and FileExists(FileName) then + begin + Sl := TStringList.Create; + try + Sl.LoadFromFile(FileName); + Sl.AddStrings(List); + Sl.SaveToFile(FileName); + finally + Sl.Free; + end; + end + else + List.SaveToFile(FileName); + + Result := True; + finally + List.Free; + end; + end; + end; +end; + +function SaveMemoryToPemStream(Stream: TStream; const Head, Tail: string; + MemoryStream: TMemoryStream; KeyEncryptMethod: TCnKeyEncryptMethod; + KeyHashMethod: TCnKeyHashMethod; const Password: string; Append: Boolean): Boolean; +var + S, EH: string; + List: TStringList; +begin + Result := False; + if (MemoryStream <> nil) and (MemoryStream.Size <> 0) then + begin + MemoryStream.Position := 0; + + if (KeyEncryptMethod <> ckeNone) and (Password <> '') then + begin + // MemoryStream + AddPKCS7Padding(MemoryStream, ENC_TYPE_BLOCK_SIZE[KeyEncryptMethod]); + + // ټ + if not EncryptPemStream(KeyHashMethod, KeyEncryptMethod, MemoryStream, Password, EH) then + Exit; + end; + + if ECN_BASE64_OK = Base64Encode(MemoryStream, S) then + begin + List := TStringList.Create; + try + SplitStringToList(S, List); + + List.Insert(0, Head); // ͨͷ + if EH <> '' then // ͷ + List.Insert(1, EH); + List.Add(Tail); // ͨβ + + if not Append then + Stream.Size := 0; + + List.SaveToStream(Stream); + + Result := True; + finally + List.Free; + end; + end; + end; +end; + +end. diff --git a/CnPack/Crypto/CnRandom.dcu b/CnPack/Crypto/CnRandom.dcu new file mode 100644 index 0000000000000000000000000000000000000000..c89e954877a4cd1e8e54c20ff7c9e1f2ca04318b GIT binary patch literal 5673 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 literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnRandom.pas b/CnPack/Crypto/CnRandom.pas new file mode 100644 index 0000000..de6a2c3 --- /dev/null +++ b/CnPack/Crypto/CnRandom.pas @@ -0,0 +1,415 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnRandom; +{* |
+================================================================================
+* ƣ
+* Ԫƣ䵥Ԫ
+* ԪߣCnPack  (master@cnpack.org)
+*     עԪװ Windows ƽ̨ MacOS/Linux ƽ̨µİȫ
+*           ṩȫ书ܡ
+* ƽ̨Win7 + Delphi 5.0
+* ݲԣWin32/Win64/MacOS/Linux + Unicode/NonUnicode
+*   õԪ豾ػ
+* ޸ļ¼2023.01.15 V1.3
+*                Windows ȫ urandom ֧ Linux
+*           2023.01.08 V1.2
+*                Win64  API 
+*           2022.08.22 V1.1
+*               ʹòϵͳṩ
+*           2020.03.27 V1.0
+*               Ԫ CnPrime ж
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils {$IFDEF MSWINDOWS}, Windows {$ENDIF}, Classes, CnNative; + +type + ECnRandomAPIError = class(Exception); + +function RandomUInt64: TUInt64; +{* UInt64 Χڵڲ֧ UInt64 ƽ̨ Int64 档 + + + ޣ + + ֵTUInt64 - UInt64 Χڵ +} + +function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; +{* شڵ 0 Сָ UInt64 ֵ + + + HighValue: TUInt64 - ָ UInt64 + + ֵTUInt64 - شڵ 0 Сָ HighValue +} + +function RandomInt64: Int64; +{* شڵ 0 С Int64 ޵ + + + ޣ + + ֵInt64 - شڵ 0 С Int64 ޵ +} + +function RandomInt64LessThan(HighValue: Int64): Int64; +{* شڵ 0 Сָ Int64 ֵб֤ HighValue 0 + + + HighValue: Int64 - ָ Int64 + + ֵInt64 - شڵ 0 Сָ HighValue +} + +function RandomUInt32: Cardinal; +{* UInt32 Χڵ + + + ޣ + + ֵCardinal - UInt32 Χڵ +} + +function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; +{* شڵ 0 Сָ UInt32 ֵ + + + HighValue: Cardinal - ָ UInt32 + + ֵCardinal - شڵ 0 Сָ HighValue +} + +function RandomInt32: Integer; +{* شڵ 0 С Int32 ޵ + + + ޣ + + ֵInteger - شڵ 0 С Int32 ޵ +} + +function RandomInt32LessThan(HighValue: Integer): Integer; +{* شڵ 0 Сָ Int32 б֤ HighValue 0 + + + HighValue: Integer - ָ Int32 + + ֵInteger - شڵ 0 Сָ HighValue +} + +function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; + ElementCount: Integer): Boolean; +{* ߵϴ㷨 ArrayBase ָԪسߴΪ ElementSize ElementCount Ԫؾϴơ + + + ArrayBase: Pointer - ϴƵڴַ + ElementByteSize: Integer - ϴƵÿڴԪҲÿһƵֽڴС + ElementCount: Integer - ڴԪҲƵ + + ֵBoolean - ϴǷɹ +} + +function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{* ʹ Windows API /dev/random 豸ʵ䣬ڲγʼ沢ͷš + + + Buf: PAnsiChar - ڴַ + BufByteLen: Integer - ڴֽڳ + + ֵBoolean - Ƿɹ +} + +function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{* ʹ Windows API /dev/urandom 豸ʵ䣬 + Windows ʹԤȳʼõ١ + + + Buf: PAnsiChar - ڴַ + BufByteLen: Integer - ڴֽڳ + + ֵBoolean - Ƿɹ +} + +implementation + +{$IFDEF MSWINDOWS} + +const + ADVAPI32 = 'advapi32.dll'; + + CRYPT_VERIFYCONTEXT = $F0000000; + CRYPT_NEWKEYSET = $8; + CRYPT_DELETEKEYSET = $10; + + PROV_RSA_FULL = 1; + NTE_BAD_KEYSET = $80090016; + +function CryptAcquireContext(phProv: PHandle; pszContainer: PAnsiChar; + pszProvider: PAnsiChar; dwProvType: LongWord; dwFlags: LongWord): BOOL; + stdcall; external ADVAPI32 name 'CryptAcquireContextA'; + +function CryptReleaseContext(hProv: THandle; dwFlags: LongWord): BOOL; + stdcall; external ADVAPI32 name 'CryptReleaseContext'; + +function CryptGenRandom(hProv: THandle; dwLen: LongWord; pbBuffer: PAnsiChar): BOOL; + stdcall; external ADVAPI32 name 'CryptGenRandom'; + +var + FHProv: THandle = 0; + +{$ELSE} + +const + DEV_FILE = '/dev/urandom'; + +{$ENDIF} + +function CnRandomFillBytes(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +var +{$IFDEF MSWINDOWS} + HProv: THandle; + Res: DWORD; + B: Boolean; +{$ELSE} + F: TFileStream; +{$ENDIF} +begin + Result := False; +{$IFDEF MSWINDOWS} + // ʹ Windows API ʵ + HProv := 0; + B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, 0); + if not B then + B := CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + + if not B then + begin + Res := GetLastError; + if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ + begin + if not CryptAcquireContext(@HProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); + end + else + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); + end; + + if HProv <> 0 then + begin + try + Result := CryptGenRandom(HProv, BufByteLen, Buf); + if not Result then + raise ECnRandomAPIError.CreateFmt('Error CryptGenRandom $%8.8x', [GetLastError]); + finally + CryptReleaseContext(HProv, 0); + end; + end; +{$ELSE} + // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ + F := nil; + try + F := TFileStream.Create(DEV_FILE, fmOpenRead); + Result := F.Read(Buf^, BufByteLen) = BufByteLen; + finally + F.Free; + end; +{$ENDIF} +end; + +function CnRandomFillBytes2(Buf: PAnsiChar; BufByteLen: Integer): Boolean; +{$IFNDEF MSWINDOWS} +var + F: TFileStream; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + Result := CryptGenRandom(FHProv, BufByteLen, Buf); +{$ELSE} + // MacOS/Linux µʵ֣öȡ /dev/urandom ݵķʽ + F := nil; + try + F := TFileStream.Create(DEV_FILE, fmOpenRead); + Result := F.Read(Buf^, BufByteLen) = BufByteLen; + finally + F.Free; + end; +{$ENDIF} +end; + +function RandomUInt64: TUInt64; +var + HL: array[0..1] of Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@HL[0], SizeOf(TUInt64)) then + begin + // ֱ Random * High(TUInt64) ܻᾫȲ Lo ȫ FF˷ֿ + Randomize; + HL[0] := Trunc(Random * High(Cardinal) - 1) + 1; + HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; + end; + + Result := (TUInt64(HL[0]) shl 32) + HL[1]; +end; + +function RandomUInt64LessThan(HighValue: TUInt64): TUInt64; +begin + Result := UInt64Mod(RandomUInt64, HighValue); +end; + +function RandomInt64LessThan(HighValue: Int64): Int64; +var + HL: array[0..1] of Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@HL[0], SizeOf(Int64)) then + begin + // ֱ Random * High(Int64) ܻᾫȲ Lo ȫ FF˷ֿ + Randomize; + HL[0] := Trunc(Random * High(Integer) - 1) + 1; // Int64 λ 1⸺ + HL[1] := Trunc(Random * High(Cardinal) - 1) + 1; + end + else + HL[0] := HL[0] mod (Cardinal(High(Integer)) + 1); // Int64 λ 1⸺ + + Result := (Int64(HL[0]) shl 32) + HL[1]; + Result := Result mod HighValue; // δ HighValue Сڵ 0 +end; + +function RandomInt64: Int64; +begin + Result := RandomInt64LessThan(High(Int64)); +end; + +function RandomUInt32: Cardinal; +var + D: Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then + begin + Randomize; + D := Trunc(Random * High(Cardinal) - 1) + 1; + end; + + Result := D; +end; + +function RandomUInt32LessThan(HighValue: Cardinal): Cardinal; +begin + Result := RandomUInt32 mod HighValue; +end; + +function RandomInt32: Integer; +begin + Result := RandomInt32LessThan(High(Integer)); +end; + +function RandomInt32LessThan(HighValue: Integer): Integer; +var + D: Cardinal; +begin + // ϵͳ + if not CnRandomFillBytes2(@D, SizeOf(Cardinal)) then + begin + Randomize; + D := Trunc(Random * High(Integer) - 1) + 1; + end + else + D := D mod (Cardinal(High(Integer)) + 1); + + Result := Integer(Int64(D) mod Int64(HighValue)); // δ HighValue Сڵ 0 +end; + +function CnKnuthShuffle(ArrayBase: Pointer; ElementByteSize: Integer; + ElementCount: Integer): Boolean; +var + I, R: Integer; + B1, B2: Pointer; +begin + Result := False; + if (ArrayBase = nil) or (ElementByteSize <= 0) or (ElementCount < 0) then // Ȳ + Exit; + + Result := True; + if ElementCount <= 1 then // ûԪػֻһԪʱϴ + Exit; + + for I := ElementCount - 1 downto 0 do + begin + R := RandomInt32LessThan(I + 1); // 0 I ڵҪ 1 + B1 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(I * ElementByteSize)); + B2 := Pointer(TCnNativeUInt(ArrayBase) + TCnNativeUInt(R * ElementByteSize)); + MemorySwap(B1, B2, ElementByteSize); + end; + Result := True; +end; + +{$IFDEF MSWINDOWS} + +procedure StartRandom; +var + Res: DWORD; + B: Boolean; +begin + FHProv := 0; + B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, 0); + if not B then + B := CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); + + if not B then + begin + Res := GetLastError; + if Res = NTE_BAD_KEYSET then // KeyContainer ڣ½ķʽ + begin + if not CryptAcquireContext(@FHProv, nil, nil, PROV_RSA_FULL, CRYPT_NEWKEYSET) then + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext NewKeySet $%8.8x', [GetLastError]); + end + else + raise ECnRandomAPIError.CreateFmt('Error CryptAcquireContext $%8.8x', [Res]); + end; +end; + +procedure StopRandom; +begin + if FHProv <> 0 then + begin + CryptReleaseContext(FHProv, 0); + FHProv := 0; + end; +end; + +initialization + StartRandom; + +finalization + StopRandom; + +{$ENDIF} + +end. diff --git a/CnPack/Crypto/CnSHA1.dcu b/CnPack/Crypto/CnSHA1.dcu new file mode 100644 index 0000000000000000000000000000000000000000..a3f75043eb9f12c9d50a84dbf880dc9592c6e5f6 GIT binary patch literal 10859 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 QlTU=35CcrI#ct;Ke<$eb%>V!Z literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnSHA1.pas b/CnPack/Crypto/CnSHA1.pas new file mode 100644 index 0000000..4daf51e --- /dev/null +++ b/CnPack/Crypto/CnSHA1.pas @@ -0,0 +1,737 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA1; +{* |
+================================================================================
+* ƣ
+* ԪƣSHA1 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           /ֲ䲿ֹܡ
+*     עԪʵ SHA1 Ӵ㷨Ӧ HMAC 㷨
+* ƽ̨PWin2000Pro + Delphi 5.0
+* ݲԣPWin9X/2000/XP + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2022.04.26 V1.5
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.12.12 V1.4
+*               ֧ TBytes
+*           2019.04.15 V1.3
+*               ֧ Win32/Win64/MacOS32
+*           2015.08.14 V1.2
+*               л Pascal ֿ֧ƽ̨
+*           2014.10.22 V1.1
+*                HMAC 
+*           2010.07.14 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +type + PCnSHA1Digest = ^TCnSHA1Digest; + TCnSHA1Digest = array[0..19] of Byte; + {* SHA1 Ӵս20 ֽ} + + TCnSHA1Context = record + {* SHA1 Ľṹ} + Hash: array[0..4] of Cardinal; + Hi, Lo: Cardinal; + Buffer: array[0..63] of Byte; + Index: Integer; + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA1CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* SHA1 ӴսȻص¼} + +function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; +{* ݿ SHA1 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; +{* ݿ SHA1 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Bytes(Data: TBytes): TCnSHA1Digest; +{* ֽ SHA1 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1String(const Str: string): TCnSHA1Digest; +{* String ݽ SHA1 㡣ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; +{* AnsiString ַ SHA1 㣬ֱӼڲݣޱ봦 + + + const Str: AnsiString - ַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1StringW(const Str: WideString): TCnSHA1Digest; +{* WideString ַת SHA1 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA1UnicodeString(const Str: string): TCnSHA1Digest; +{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$ELSE} + +function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; +{* UnicodeString ݽֱӵ SHA1 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +{$ENDIF} + +function SHA1File(const FileName: string; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +{* ָļݽ SHA1 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +function SHA1Stream(Stream: TStream; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +{* ָݽ SHA1 㡣 + + + Stream: TStream - + CallBack: TCnSHA1CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA1Digest - ص SHA1 Ӵֵ +} + +// ⲿݽɢ SHA1 㣬SHA1Update ɶα + +procedure SHA1Init(var Context: TCnSHA1Context); +{* ʼһ SHA1 ģ׼ SHA1 + + + var Context: TCnSHA1Context - ʼ SHA1 + + ֵޣ +} + +procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); +{* ԳʼĶһݽ SHA1 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA1Context - SHA1 + Input: PAnsiChar - ݿַ + ByteLength: Integer - ݿֽڳ + + ֵޣ +} + +procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); +{* ּ㣬 SHA1 Digest С + + + var Context: TCnSHA1Context - SHA1 + var Digest: TCnSHA1Digest - ص SHA1 Ӵֵ + + ֵޣ +} + +function SHA1Print(const Digest: TCnSHA1Digest): string; +{* ʮƸʽ SHA1 Ӵֵ + + + const Digest: TCnSHA1Digest - ָ SHA1 Ӵֵ + + ֵstring - ʮַ +} + +function SHA1Match(const D1: TCnSHA1Digest; const D2: TCnSHA1Digest): Boolean; +{* Ƚ SHA1 ӴֵǷȡ + + + const D1: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵһ + const D2: TCnSHA1Digest - Ƚϵ SHA1 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; +{* SHA1 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA1Digest - ת SHA1 Ӵֵ + + ֵstring - صַ +} + +procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA1Digest); +{* SHA1 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA1 Կݿַ + KeyByteLength: Integer - SHA1 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA1Digest - ص SHA1 Ӵֵ + + ֵޣ +} + +implementation + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_SHA1_BLOCK_SIZE_BYTE = 64; + HMAC_SHA1_OUTPUT_LENGTH_BYTE = 20; + +function LRot32(X: Cardinal; C: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X shl (C and 31) + X shr (32 - C and 31); +end; + +function F1(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := z xor (x and (y xor z)); +end; + +function F2(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := x xor y xor z; +end; + +function F3(x, y, z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (x and y) or (z and (x or y)); +end; + +function RB(A: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (A shr 24) or ((A shr 8) and $FF00) or ((A shl 8) and $FF0000) or (A shl 24); +end; + +procedure SHA1Compress(var Data: TCnSHA1Context); +var + A, B, C, D, E, T: Cardinal; + W: array[0..79] of Cardinal; + I: Integer; +begin + Move(Data.Buffer, W, Sizeof(Data.Buffer)); + for I := 0 to 15 do + W[I] := RB(W[I]); + for I := 16 to 79 do + W[I] := LRot32(W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16], 1); + A := Data.Hash[0]; + B := Data.Hash[1]; + C := Data.Hash[2]; + D := Data.Hash[3]; + E := Data.Hash[4]; + for I := 0 to 19 do + begin + T := LRot32(A, 5) + F1(B, C, D) + E + W[I] + $5A827999; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 20 to 39 do + begin + T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $6ED9EBA1; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 40 to 59 do + begin + T := LRot32(A, 5) + F3(B, C, D) + E + W[I] + $8F1BBCDC; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + for I := 60 to 79 do + begin + T := LRot32(A, 5) + F2(B, C, D) + E + W[I] + $CA62C1D6; + E := D; + D := C; + C := LRot32(B, 30); + B := A; + A := T; + end; + Data.Hash[0] := Data.Hash[0] + A; + Data.Hash[1] := Data.Hash[1] + B; + Data.Hash[2] := Data.Hash[2] + C; + Data.Hash[3] := Data.Hash[3] + D; + Data.Hash[4] := Data.Hash[4] + E; + FillChar(W, Sizeof(W), 0); + FillChar(Data.Buffer, Sizeof(Data.Buffer), 0); +end; + +procedure SHA1Init(var Context: TCnSHA1Context); +begin + Context.Hi := 0; + Context.Lo := 0; + Context.Index := 0; + FillChar(Context.Buffer, Sizeof(Context.Buffer), 0); + Context.Hash[0] := $67452301; + Context.Hash[1] := $EFCDAB89; + Context.Hash[2] := $98BADCFE; + Context.Hash[3] := $10325476; + Context.Hash[4] := $C3D2E1F0; +end; + +procedure SHA1UpdateLen(var Context: TCnSHA1Context; Len: Integer); +var + I: Cardinal; + K: Integer; +begin + for K := 0 to 7 do + begin + I := Context.Lo; + Inc(Context.Lo, Len); + if Context.Lo < I then + Inc(Context.Hi); + end; +end; + +procedure SHA1Update(var Context: TCnSHA1Context; Input: PAnsiChar; ByteLength: Integer); +begin + SHA1UpdateLen(Context, ByteLength); + while ByteLength > 0 do + begin + Context.Buffer[Context.Index] := PByte(Input)^; + Inc(PByte(Input)); + Inc(Context.Index); + Dec(ByteLength); + if Context.Index = 64 then + begin + Context.Index := 0; + SHA1Compress(Context); + end; + end; +end; + +procedure SHA1UpdateW(var Context: TCnSHA1Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + SHA1Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA1Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA1Final(var Context: TCnSHA1Context; var Digest: TCnSHA1Digest); +type + PDWord = ^Cardinal; +begin + Context.Buffer[Context.Index] := $80; + if Context.Index >= 56 then + SHA1Compress(Context); + PDWord(@Context.Buffer[56])^ := RB(Context.Hi); + PDWord(@Context.Buffer[60])^ := RB(Context.Lo); + SHA1Compress(Context); + Context.Hash[0] := RB(Context.Hash[0]); + Context.Hash[1] := RB(Context.Hash[1]); + Context.Hash[2] := RB(Context.Hash[2]); + Context.Hash[3] := RB(Context.Hash[3]); + Context.Hash[4] := RB(Context.Hash[4]); + Move(Context.Hash, Digest, Sizeof(Digest)); +end; + +// ݿ SHA1 +function SHA1(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, Input, ByteLength); + SHA1Final(Context, Result); +end; + +// ݿ SHA1 +function SHA1Buffer(const Buffer; Count: Cardinal): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(Buffer), Count); + SHA1Final(Context, Result); +end; + +function SHA1Bytes(Data: TBytes): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA1Final(Context, Result); +end; + +// String ݽ SHA1 +function SHA1String(const Str: string): TCnSHA1Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA1StringA(AStr); +end; + +// AnsiString ݽ SHA1 +function SHA1StringA(const Str: AnsiString): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(Str), Length(Str)); + SHA1Final(Context, Result); +end; + +// WideString ݽ SHA1 +function SHA1StringW(const Str: WideString): TCnSHA1Digest; +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1UpdateW(Context, PWideChar(Str), Length(Str)); + SHA1Final(Context, Result); +end; + +{$IFDEF UNICODE} +function SHA1UnicodeString(const Str: string): TCnSHA1Digest; +{$ELSE} +function SHA1UnicodeString(const Str: WideString): TCnSHA1Digest; +{$ENDIF} +var + Context: TCnSHA1Context; +begin + SHA1Init(Context); + SHA1Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA1Final(Context, Result); +end; + +function InternalSHA1Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHA1Digest; CallBack: TCnSHA1CalcProgressFunc = nil): Boolean; +var + Context: TCnSHA1Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then Exit; + if Size < BufSize then BufLen := Size + else BufLen := BufSize; + + CancelCalc := False; + SHA1Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA1Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA1Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA1 +function SHA1Stream(Stream: TStream; + CallBack: TCnSHA1CalcProgressFunc = nil): TCnSHA1Digest; +begin + InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +// ָļݽ SHA1 +function SHA1File(const FileName: string; + CallBack: TCnSHA1CalcProgressFunc): TCnSHA1Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnSHA1Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA1Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA1Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA1Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA1Final(Context, Result); +{$ENDIF} + end; +end; + +// ʮƸʽ SHA1 Ӵֵ +function SHA1Print(const Digest: TCnSHA1Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA1Digest)); +end; + +// Ƚ SHA1 ӴֵǷ +function SHA1Match(const D1, D2: TCnSHA1Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 20) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// SHA1 Ӵֵת string +function SHA1DigestToStr(const Digest: TCnSHA1Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA1Digest)); +end; + +procedure SHA1HmacInit(var Ctx: TCnSHA1Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA1Digest; +begin + if KeyLength > HMAC_SHA1_BLOCK_SIZE_BYTE then + begin + Sum := SHA1Buffer(Key, KeyLength); + KeyLength := HMAC_SHA1_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_SHA1_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_SHA1_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + SHA1Init(Ctx); + SHA1Update(Ctx, @(Ctx.Ipad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); +end; + +procedure SHA1HmacUpdate(var Ctx: TCnSHA1Context; Input: PAnsiChar; Length: Cardinal); +begin + SHA1Update(Ctx, Input, Length); +end; + +procedure SHA1HmacFinal(var Ctx: TCnSHA1Context; var Output: TCnSHA1Digest); +var + Len: Integer; + TmpBuf: TCnSHA1Digest; +begin + Len := HMAC_SHA1_OUTPUT_LENGTH_BYTE; + SHA1Final(Ctx, TmpBuf); + SHA1Init(Ctx); + SHA1Update(Ctx, @(Ctx.Opad[0]), HMAC_SHA1_BLOCK_SIZE_BYTE); + SHA1Update(Ctx, @(TmpBuf[0]), Len); + SHA1Final(Ctx, Output); +end; + +procedure SHA1Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA1Digest); +var + Ctx: TCnSHA1Context; +begin + SHA1HmacInit(Ctx, Key, KeyByteLength); + SHA1HmacUpdate(Ctx, Input, ByteLength); + SHA1HmacFinal(Ctx, Output); +end; + +end. diff --git a/CnPack/Crypto/CnSHA2.dcu b/CnPack/Crypto/CnSHA2.dcu new file mode 100644 index 0000000000000000000000000000000000000000..b080c2a50656f8ebf30bc3076405071038294457 GIT binary patch literal 30907 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 +================================================================================ +* ƣ +* ԪƣSHA2 Ӵ㷨ʵֵԪ +* ԪߣCnPack (master@cnpack.org) +* / C Pascal ֲ䲿ֹܡ +* עԪʵ SHA2 ϵӴ㷨Ӧ HMAC 㷨 SHA224/256/384/512 +* עDelphi 5/6/7 Ԫз Int64 ޷ UInt64 SHA512/384 +* ԭǻڲ޷ļӼλԼƵȶͬΨһ +* ͬDZȽϣԪûƵıȽϡ +* ƽ̨PWinXP + Delphi 5.0 +* ݲԣPWinXP/7 + Delphi 5/6 +* õԪеַϱػʽ +* ޸ļ¼2022.04.26 V1.4 +* ޸ LongWord Integer ַת֧ MacOS64 +* 2019.04.15 V1.3 +* ֧ Win32/Win64/MacOS32 +* 2017.10.31 V1.2 +* SHA512/384 HMAC +* 2016.09.30 V1.1 +* ʵ SHA512/384D567з Int64 ޷ UInt64 +* 2016.09.27 V1.0 +* Ԫ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +type + PCnSHAGeneralDigest = ^TCnSHAGeneralDigest; + TCnSHAGeneralDigest = array[0..63] of Byte; + + PCnSHA224Digest = ^TCnSHA224Digest; + TCnSHA224Digest = array[0..27] of Byte; + {* SHA224 Ӵս28 ֽ} + + PCnSHA256Digest = ^TCnSHA256Digest; + TCnSHA256Digest = array[0..31] of Byte; + {* SHA256 Ӵս32 ֽ} + + PCnSHA384Digest = ^TCnSHA384Digest; + TCnSHA384Digest = array[0..47] of Byte; + {* SHA384 Ӵս48 ֽ} + + PCnSHA512Digest = ^TCnSHA512Digest; + TCnSHA512Digest = array[0..63] of Byte; + {* SHA512 Ӵս64 ֽ} + + TCnSHA256Context = packed record + {* SHA256 Ľṹ} + DataLen: Cardinal; + Data: array[0..63] of Byte; + BitLen: Int64; + State: array[0..7] of Cardinal; + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA224Context = TCnSHA256Context; + {* SHA224 Ľṹ} + + TCnSHA512Context = packed record + {* SHA512 Ľṹ} + DataLen: Cardinal; + Data: array[0..127] of Byte; + TotalLen: Int64; + State: array[0..7] of Int64; + Ipad: array[0..127] of Byte; {!< HMAC: inner padding } + Opad: array[0..127] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA384Context = TCnSHA512Context; + {* SHA512 Ľṹ} + + TCnSHACalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: + Boolean) of object; + {* SHA2 ϵӴսȻص¼} + +function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; +{* ݿ SHA224 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; +{* ݿ SHA256 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; +{* ݿ SHA384 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; +{* ݿ SHA512 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; +{* ݿ SHA224 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; +{* ݿ SHA256 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; +{* ݿ SHA384 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; +{* ݿ SHA512 㡣 + + + const Buffer - ݿַ + Count: Cardinal - + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224Bytes(Data: TBytes): TCnSHA224Digest; +{* ֽ SHA224 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256Bytes(Data: TBytes): TCnSHA256Digest; +{* ֽ SHA256 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384Bytes(Data: TBytes): TCnSHA384Digest; +{* ֽ SHA384 㡣 + + Data: TBytes - ֽ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512Bytes(Data: TBytes): TCnSHA512Digest; +{* ֽ SHA512 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA224String(const Str: string): TCnSHA224Digest; +{* String ݽ SHA224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256String(const Str: string): TCnSHA256Digest; +{* String ݽ SHA256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384String(const Str: string): TCnSHA384Digest; +{* String ݽ SHA384 㣬ע D2009ϰ汾string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512String(const Str: string): TCnSHA512Digest; +{* String ݽ SHA512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + + +function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; +{* AnsiString ݽ SHA224 㡣 + + + const Str: AnsiString - + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA224StringW(const Str: WideString): TCnSHA224Digest; +{* WideString ݽ SHA224 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; +{* AnsiString ݽ SHA256 㡣 + + + const Str: AnsiString - + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA256StringW(const Str: WideString): TCnSHA256Digest; +{* WideString ݽ SHA256 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; +{* AnsiString ݽ SHA384 㡣 + + + const Str: AnsiString - + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA384StringW(const Str: WideString): TCnSHA384Digest; +{* WideString ݽ SHA384 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; +{* AnsiString ݽ SHA512 㡣 + + + const Str: AnsiString - + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA512StringW(const Str: WideString): TCnSHA512Digest; +{* WideString ݽ SHA512 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA224UnicodeString(const Str: string): TCnSHA224Digest; +{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256UnicodeString(const Str: string): TCnSHA256Digest; +{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384UnicodeString(const Str: string): TCnSHA384Digest; +{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512UnicodeString(const Str: string): TCnSHA512Digest; +{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$ELSE} + +function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; +{* UnicodeString ݽֱӵ SHA224 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; +{* UnicodeString ݽֱӵ SHA256 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; +{* UnicodeString ݽֱӵ SHA384 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; +{* UnicodeString ݽֱӵ SHA512 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +{$ENDIF} + +function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA224Digest; +{* ָļݽ SHA256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA224Digest; +{* ָݽ SHA224 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA224Digest - ص SHA224 Ӵֵ +} + +function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA256Digest; +{* ָļݽ SHA256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA256Digest; +{* ָݽ SHA256 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA256Digest - ص SHA256 Ӵֵ +} + +function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA384Digest; +{* ָļݽ SHA384 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA384Digest; +{* ָݽ SHA384 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA384Digest - ص SHA384Ӵֵ +} + +function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc = + nil): TCnSHA512Digest; +{* ָļݽ SHA512 㡣 + + + const FileName: string - ļ + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA512Digest; +{* ָݽ SHA512 㡣 + + + Stream: TStream - + CallBack: TCnSHACalcProgressFunc - ȻصĬΪ + + ֵTCnSHA512Digest - ص SHA512 Ӵֵ +} + +// ⲿݽɢ SHA224 㣬SHA224Update ɶα + +procedure SHA224Init(var Context: TCnSHA224Context); +{* ʼһ SHA224 ģ׼ SHA224 + + + var Context: TCnSHA224Context - ʼ SHA224 + + ֵޣ +} + +procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA224 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA224Context - SHA224 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); +{* ּ㣬 SHA224 Digest С + + + var Context: TCnSHA224Context - SHA224 + var Digest: TCnSHA224Digest - ص SHA224 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA256 㣬SHA256Update ɶα + +procedure SHA256Init(var Context: TCnSHA256Context); +{* ʼһ SHA256 ģ׼ SHA256 + + + var Context: TCnSHA256Context - ʼ SHA256 + + ֵޣ +} + +procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA256Context - SHA256 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); +{* ּ㣬 SHA256 Digest С + + + var Context: TCnSHA256Context - SHA256 + var Digest: TCnSHA256Digest - ص SHA256 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA384 㣬SHA384Update ɶα + +procedure SHA384Init(var Context: TCnSHA384Context); +{* ʼһ SHA384 ģ׼ SHA384 + + + var Context: TCnSHA384Context - ʼ SHA384 + + ֵޣ +} + +procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA384 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA384Context - SHA384 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); +{* ּ㣬 SHA384 Digest С + + + var Context: TCnSHA384Context - SHA384 + var Digest: TCnSHA384Digest - ص SHA384 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA512 㣬SHA512Update ɶα + +procedure SHA512Init(var Context: TCnSHA512Context); +{* ʼһ SHA512 ģ׼ SHA512 + + + var Context: TCnSHA512Context - ʼ SHA512 + + ֵޣ +} + +procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA512 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA512Context - SHA512 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); +{* ּ㣬 SHA512 Digest + + + var Context: TCnSHA512Context - SHA512 + var Digest: TCnSHA512Digest - ص SHA512 Ӵֵ + + ֵޣ +} + +function SHA224Print(const Digest: TCnSHA224Digest): string; +{* ʮƸʽ SHA224 Ӵֵ + + + const Digest: TCnSHA224Digest - ָ SHA224 Ӵֵ + + ֵstring - ʮַ +} + +function SHA256Print(const Digest: TCnSHA256Digest): string; +{* ʮƸʽ SHA256 Ӵֵ + + + const Digest: TCnSHA256Digest - ָ SHA256 Ӵֵ + + ֵstring - ʮַ +} + +function SHA384Print(const Digest: TCnSHA384Digest): string; +{* ʮƸʽ SHA384 Ӵֵ + + + const Digest: TCnSHA384Digest - ָ SHA384 Ӵֵ + + ֵstring - ʮַ +} + +function SHA512Print(const Digest: TCnSHA512Digest): string; +{* ʮƸʽ SHA512 Ӵֵ + + + const Digest: TCnSHA512Digest - ָ SHA512 Ӵֵ + + ֵstring - ʮַ +} + +function SHA224Match(const D1: TCnSHA224Digest; const D2: TCnSHA224Digest): Boolean; +{* Ƚ SHA224 ӴֵǷȡ + + + const D1: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵһ + const D2: TCnSHA224Digest - Ƚϵ SHA224 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA256Match(const D1: TCnSHA256Digest; const D2: TCnSHA256Digest): Boolean; +{* Ƚ SHA256 ӴֵǷȡ + + + const D1: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵһ + const D2: TCnSHA256Digest - Ƚϵ SHA256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA384Match(const D1: TCnSHA384Digest; const D2: TCnSHA384Digest): Boolean; +{* Ƚ SHA384 ӴֵǷȡ + + + const D1: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵһ + const D2: TCnSHA384Digest - Ƚϵ SHA384 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA512Match(const D1: TCnSHA512Digest; const D2: TCnSHA512Digest): Boolean; +{* Ƚ SHA512 ӴֵǷȡ + + + const D1: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵһ + const D2: TCnSHA512Digest - Ƚϵ SHA512 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; +{* SHA224 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA224Digest - ת SHA224 Ӵֵ + + ֵstring - صַ +} + +function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; +{* SHA256 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA256Digest - ת SHA256 Ӵֵ + + ֵstring - صַ +} + +function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; +{* SHA384 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA384Digest - ת SHA384 Ӵֵ + + ֵstring - صַ +} + +function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; +{* SHA512 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA512Digest - ת SHA512 Ӵֵ + + ֵstring - صַ +} + +procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA224Digest); +{* SHA224 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA224 Կݿַ + KeyByteLength: Integer - SHA224 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA224Digest - ص SHA224 Ӵֵ + + ֵޣ +} + +procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA256Digest); +{* SHA256 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA256 Կݿַ + KeyByteLength: Integer - SHA256 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA256Digest - ص SHA256 Ӵֵ + + ֵޣ +} + +procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA384Digest); +{* SHA384 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA384 Կݿַ + KeyByteLength: Integer - SHA384 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA384Digest - ص SHA384 Ӵֵ + + ֵޣ +} + +procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA512Digest); +{* SHA512 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA512 Կݿַ + KeyByteLength: Integer - SHA512 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA512Digest - ص SHA512 Ӵֵ + + ֵޣ +} + +implementation + +const + HMAC_SHA2_224_256_BLOCK_SIZE_BYTE = 64; + HMAC_SHA2_384_512_BLOCK_SIZE_BYTE = 128; + + HMAC_SHA2_224_OUTPUT_LENGTH_BYTE = 28; + HMAC_SHA2_256_OUTPUT_LENGTH_BYTE = 32; + HMAC_SHA2_384_OUTPUT_LENGTH_BYTE = 48; + HMAC_SHA2_512_OUTPUT_LENGTH_BYTE = 64; + +type + TSHA2Type = (stSHA2_224, stSHA2_256, stSHA2_384, stSHA2_512); + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + KEYS256: array[0..63] of Cardinal = ($428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, + $3956C25B, $59F111F1, $923F82A4, $AB1C5ED5, $D807AA98, $12835B01, $243185BE, + $550C7DC3, $72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, $E49B69C1, $EFBE4786, + $0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA, $983E5152, + $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147, $06CA6351, $14292967, + $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13, $650A7354, $766A0ABB, $81C2C92E, + $92722C85, $A2BFE8A1, $A81A664B, $C24B8B70, $C76C51A3, $D192E819, $D6990624, + $F40E3585, $106AA070, $19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, + $4ED8AA4A, $5B9CCA4F, $682E6FF3, $748F82EE, $78A5636F, $84C87814, $8CC70208, + $90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2); + + KEYS512: array[0..79] of TUInt64 = ($428A2F98D728AE22, $7137449123EF65CD, + $B5C0FBCFEC4D3B2F, $E9B5DBA58189DBBC, $3956C25BF348B538, $59F111F1B605D019, + $923F82A4AF194F9B, $AB1C5ED5DA6D8118, $D807AA98A3030242, $12835B0145706FBE, + $243185BE4EE4B28C, $550C7DC3D5FFB4E2, $72BE5D74F27B896F, $80DEB1FE3B1696B1, + $9BDC06A725C71235, $C19BF174CF692694, $E49B69C19EF14AD2, $EFBE4786384F25E3, + $0FC19DC68B8CD5B5, $240CA1CC77AC9C65, $2DE92C6F592B0275, $4A7484AA6EA6E483, + $5CB0A9DCBD41FBD4, $76F988DA831153B5, $983E5152EE66DFAB, $A831C66D2DB43210, + $B00327C898FB213F, $BF597FC7BEEF0EE4, $C6E00BF33DA88FC2, $D5A79147930AA725, + $06CA6351E003826F, $142929670A0E6E70, $27B70A8546D22FFC, $2E1B21385C26C926, + $4D2C6DFC5AC42AED, $53380D139D95B3DF, $650A73548BAF63DE, $766A0ABB3C77B2A8, + $81C2C92E47EDAEE6, $92722C851482353B, $A2BFE8A14CF10364, $A81A664BBC423001, + $C24B8B70D0F89791, $C76C51A30654BE30, $D192E819D6EF5218, $D69906245565A910, + $F40E35855771202A, $106AA07032BBD1B8, $19A4C116B8D2D0C8, $1E376C085141AB53, + $2748774CDF8EEB99, $34B0BCB5E19B48A8, $391C0CB3C5C95A63, $4ED8AA4AE3418ACB, + $5B9CCA4F7763E373, $682E6FF3D6B2B8A3, $748F82EE5DEFB2FC, $78A5636F43172F60, + $84C87814A1F0AB72, $8CC702081A6439EC, $90BEFFFA23631E28, $A4506CEBDE82BDE9, + $BEF9A3F7B2C67915, $C67178F2E372532B, $CA273ECEEA26619C, $D186B8C721C0C207, + $EADA7DD6CDE0EB1E, $F57D4F7FEE6ED178, $06F067AA72176FBA, $0A637DC5A2C898A6, + $113F9804BEF90DAE, $1B710B35131C471B, $28DB77F523047D84, $32CAAB7B40C72493, + $3C9EBE0A15C9BEBC, $431D67C49C100D4C, $4CC5D4BECB3E42B6, $597F299CFC657E2A, + $5FCB6FAB3AD6FAEC, $6C44198C4A475817); + +function ROTRight256(A, B: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (A shr B) or (A shl (32 - B)); +end; + +function ROTRight512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X shr Y) or (X shl (64 - Y)); +end; + +function SHR512(X: TUInt64; Y: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and $FFFFFFFFFFFFFFFF) shr Y; +end; + +function CH256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) xor ((not X) and Z); +end; + +function CH512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (((Y xor Z) and X) xor Z); +end; + +function MAJ256(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) xor (X and Z) xor (Y and Z); +end; + +function MAJ512(X, Y, Z: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ((X or Y) and Z) or (X and Y); +end; + +function EP0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 2) xor ROTRight256(X, 13) xor ROTRight256(X, 22); +end; + +function EP1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 6) xor ROTRight256(X, 11) xor ROTRight256(X, 25); +end; + +function SIG0256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 7) xor ROTRight256(X, 18) xor (X shr 3); +end; + +function SIG1256(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight256(X, 17) xor ROTRight256(X, 19) xor (X shr 10); +end; + +function SIG0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 28) xor ROTRight512(X, 34) xor ROTRight512(X, 39); +end; + +function SIG1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 14) xor ROTRight512(X, 18) xor ROTRight512(X, 41); +end; + +function Gamma0512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 1) xor ROTRight512(X, 8) xor SHR512(X, 7); +end; + +function Gamma1512(X: TUInt64): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := ROTRight512(X, 19) xor ROTRight512(X, 61) xor SHR512(X, 6); +end; + +procedure SHA256Transform(var Context: TCnSHA256Context; Data: PAnsiChar); +var + A, B, C, D, E, F, G, H, T1, T2: Cardinal; + M: array[0..63] of Cardinal; + I, J: Integer; +begin + I := 0; + J := 0; + while I < 16 do + begin + M[I] := (Cardinal(Data[J]) shl 24) or (Cardinal(Data[J + 1]) shl 16) or (Cardinal(Data + [J + 2]) shl 8) or Cardinal(Data[J + 3]); + Inc(I); + Inc(J, 4); + end; + + while I < 64 do + begin + M[I] := SIG1256(M[I - 2]) + M[I - 7] + SIG0256(M[I - 15]) + M[I - 16]; + Inc(I); + end; + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + I := 0; + while I < 64 do + begin + T1 := H + EP1256(E) + CH256(E, F, G) + KEYS256[I] + M[I]; + T2 := EP0256(A) + MAJ256(A, B, C); + H := G; + G := F; + F := E; + E := D + T1; + D := C; + C := B; + B := A; + A := T1 + T2; + Inc(I); + end; + + Context.State[0] := Context.State[0] + A; + Context.State[1] := Context.State[1] + B; + Context.State[2] := Context.State[2] + C; + Context.State[3] := Context.State[3] + D; + Context.State[4] := Context.State[4] + E; + Context.State[5] := Context.State[5] + F; + Context.State[6] := Context.State[6] + G; + Context.State[7] := Context.State[7] + H; +end; + +{$WARNINGS OFF} + +procedure SHA512Transform(var Context: TCnSHA512Context; Data: PAnsiChar; BlockCount: Integer); +var + A, B, C, D, E, F, G, H, T1, T2: TUInt64; + M: array[0..79] of TUInt64; + I, J, K: Integer; + OrigData: PAnsiChar; +begin + OrigData := Data; + for K := 0 to BlockCount - 1 do + begin + Data := PAnsiChar(TCnNativeInt(OrigData) + (K shl 7)); + + I := 0; + J := 0; + while I < 16 do + begin + M[I] := (TUInt64(Data[J]) shl 56) or (TUInt64(Data[J + 1]) shl 48) or + (TUInt64(Data[J + 2]) shl 40) or (TUInt64(Data[J + 3]) shl 32) or + (TUInt64(Data[J + 4]) shl 24) or (TUInt64(Data[J + 5]) shl 16) or + (TUInt64(Data[J + 6]) shl 8) or TUInt64(Data[J + 7]); + Inc(I); + Inc(J, 8); + end; + + while I < 80 do + begin + M[I] := Gamma1512(M[I - 2]) + M[I - 7] + Gamma0512(M[I - 15]) + M[I - 16]; + Inc(I); + end; + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + I := 0; + while I < 80 do + begin + T1 := H + SIG1512(E) + CH512(E, F, G) + KEYS512[I] + M[I]; + T2 := SIG0512(A) + MAJ512(A, B, C); + H := G; + G := F; + F := E; + E := D + T1; + D := C; + C := B; + B := A; + A := T1 + T2; + Inc(I); + end; + + // з޷ WarningӰ + Context.State[0] := Context.State[0] + A; + Context.State[1] := Context.State[1] + B; + Context.State[2] := Context.State[2] + C; + Context.State[3] := Context.State[3] + D; + Context.State[4] := Context.State[4] + E; + Context.State[5] := Context.State[5] + F; + Context.State[6] := Context.State[6] + G; + Context.State[7] := Context.State[7] + H; + end; +end; + +{$WARNINGS ON} + +procedure SHA224Init(var Context: TCnSHA224Context); +begin + Context.DataLen := 0; + Context.BitLen := 0; + Context.State[0] := $C1059ED8; + Context.State[1] := $367CD507; + Context.State[2] := $3070DD17; + Context.State[3] := $F70E5939; + Context.State[4] := $FFC00B31; + Context.State[5] := $68581511; + Context.State[6] := $64F98FA7; + Context.State[7] := $BEFA4FA4; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +procedure SHA224Update(var Context: TCnSHA224Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA256Update(Context, Input, ByteLength); +end; + +procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); forward; + +procedure SHA224UpdateW(var Context: TCnSHA224Context; Input: PWideChar; CharLength: Cardinal); +begin + SHA256UpdateW(Context, Input, CharLength); +end; + +procedure SHA224Final(var Context: TCnSHA224Context; var Digest: TCnSHA224Digest); +var + Dig: TCnSHA256Digest; +begin + SHA256Final(Context, Dig); + Move(Dig[0], Digest[0], SizeOf(TCnSHA224Digest)); +end; + +procedure SHA256Init(var Context: TCnSHA256Context); +begin + Context.DataLen := 0; + Context.BitLen := 0; + Context.State[0] := $6A09E667; + Context.State[1] := $BB67AE85; + Context.State[2] := $3C6EF372; + Context.State[3] := $A54FF53A; + Context.State[4] := $510E527F; + Context.State[5] := $9B05688C; + Context.State[6] := $1F83D9AB; + Context.State[7] := $5BE0CD19; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +procedure SHA256Update(var Context: TCnSHA256Context; Input: PAnsiChar; ByteLength: Cardinal); +var + I: Integer; +begin + for I := 0 to ByteLength - 1 do + begin + Context.Data[Context.DataLen] := Byte(Input[I]); + Inc(Context.DataLen); + if Context.DataLen = 64 then + begin + SHA256Transform(Context, @Context.Data[0]); + Context.BitLen := Context.BitLen + 512; + Context.DataLen := 0; + end; + end; +end; + +procedure SHA256UpdateW(var Context: TCnSHA256Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA256Update(Context, Content, iLen); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA256Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA256Final(var Context: TCnSHA256Context; var Digest: TCnSHA256Digest); +var + I: Integer; +begin + I := Context.DataLen; + Context.Data[I] := $80; + Inc(I); + + if Context.Datalen < 56 then + begin + while I < 56 do + begin + Context.Data[I] := 0; + Inc(I); + end; + end + else + begin + while I < 64 do + begin + Context.Data[I] := 0; + Inc(I); + end; + + SHA256Transform(Context, @(Context.Data[0])); + FillChar(Context.Data, 56, 0); + end; + + Context.BitLen := Context.BitLen + Context.DataLen * 8; + Context.Data[63] := Context.Bitlen; + Context.Data[62] := Context.Bitlen shr 8; + Context.Data[61] := Context.Bitlen shr 16; + Context.Data[60] := Context.Bitlen shr 24; + Context.Data[59] := Context.Bitlen shr 32; + Context.Data[58] := Context.Bitlen shr 40; + Context.Data[57] := Context.Bitlen shr 48; + Context.Data[56] := Context.Bitlen shr 56; + SHA256Transform(Context, @(Context.Data[0])); + + for I := 0 to 3 do + begin + Digest[I] := (Context.State[0] shr (24 - I * 8)) and $000000FF; + Digest[I + 4] := (Context.State[1] shr (24 - I * 8)) and $000000FF; + Digest[I + 8] := (Context.State[2] shr (24 - I * 8)) and $000000FF; + Digest[I + 12] := (Context.State[3] shr (24 - I * 8)) and $000000FF; + Digest[I + 16] := (Context.State[4] shr (24 - I * 8)) and $000000FF; + Digest[I + 20] := (Context.State[5] shr (24 - I * 8)) and $000000FF; + Digest[I + 24] := (Context.State[6] shr (24 - I * 8)) and $000000FF; + Digest[I + 28] := (Context.State[7] shr (24 - I * 8)) and $000000FF; + end; +end; + +{$WARNINGS OFF} + +procedure SHA384Init(var Context: TCnSHA384Context); +begin + Context.DataLen := 0; + Context.TotalLen := 0; + Context.State[0] := $CBBB9D5DC1059ED8; + Context.State[1] := $629A292A367CD507; + Context.State[2] := $9159015A3070DD17; + Context.State[3] := $152FECD8F70E5939; + Context.State[4] := $67332667FFC00B31; + Context.State[5] := $8EB44A8768581511; + Context.State[6] := $DB0C2E0D64F98FA7; + Context.State[7] := $47B5481DBEFA4FA4; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +{$WARNINGS ON} + +procedure SHA384Update(var Context: TCnSHA384Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA512Update(Context, Input, ByteLength); +end; + +procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); forward; + +procedure SHA384UpdateW(var Context: TCnSHA384Context; Input: PWideChar; CharLength: Cardinal); +begin + SHA512UpdateW(Context, Input, CharLength); +end; + +procedure SHA384Final(var Context: TCnSHA384Context; var Digest: TCnSHA384Digest); +var + Dig: TCnSHA512Digest; +begin + SHA512Final(Context, Dig); + Move(Dig[0], Digest[0], SizeOf(TCnSHA384Digest)); +end; + +{$WARNINGS OFF} + +procedure SHA512Init(var Context: TCnSHA512Context); +begin + Context.DataLen := 0; + Context.TotalLen := 0; + Context.State[0] := $6A09E667F3BCC908; + Context.State[1] := $BB67AE8584CAA73B; + Context.State[2] := $3C6EF372FE94F82B; + Context.State[3] := $A54FF53A5F1D36F1; + Context.State[4] := $510E527FADE682D1; + Context.State[5] := $9B05688C2B3E6C1F; + Context.State[6] := $1F83D9ABFB41BD6B; + Context.State[7] := $5BE0CD19137E2179; + FillChar(Context.Data, SizeOf(Context.Data), 0); +end; + +{$WARNINGS ON} + +procedure SHA512Update(var Context: TCnSHA512Context; Input: PAnsiChar; ByteLength: Cardinal); +var + TempLength, RemainLength, NewLength, BlockCount: Cardinal; +begin + TempLength := 128 - Context.DataLen; + if ByteLength < TempLength then + RemainLength := ByteLength + else + RemainLength := TempLength; + + Move(Input^, Context.Data[Context.DataLen], RemainLength); + if Context.DataLen + ByteLength < 128 then + begin + Inc(Context.DataLen, ByteLength); + Exit; + end; + + NewLength := Cardinal(ByteLength) - RemainLength; + BlockCount := NewLength div 128; + Input := PAnsiChar(TCnNativeUInt(Input) + RemainLength); + + SHA512Transform(Context, @Context.Data[0], 1); + SHA512Transform(Context, Input, BlockCount); + + RemainLength := NewLength mod 128; + Input := PAnsiChar(TCnNativeUInt(Input) + (BlockCount shl 7)); + Move(Input^, Context.Data[Context.DataLen], RemainLength); + + Context.DataLen := RemainLength; + Inc(Context.TotalLen, (BlockCount + 1) shl 7); +end; + +procedure SHA512UpdateW(var Context: TCnSHA512Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA512Update(Context, Content, iLen); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA512Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SHA512Final(var Context: TCnSHA512Context; var Digest: TCnSHA512Digest); +var + I: Integer; + BlockCount, BitLength, PmLength: Cardinal; +begin + if (Context.DataLen mod 128) > 111 then + BlockCount := 2 + else + BlockCount := 1; + + BitLength := (Context.TotalLen + Context.DataLen) shl 3; + PmLength := BlockCount shl 7; + FillChar(Context.Data[Context.DataLen], PmLength - Context.DataLen, 0); + Context.Data[Context.DataLen] := $80; + + Context.Data[PmLength - 1] := Byte(BitLength); + Context.Data[PmLength - 2] := Byte(BitLength shr 8); + Context.Data[PmLength - 3] := Byte(BitLength shr 16); + Context.Data[PmLength - 4] := Byte(BitLength shr 24); + + SHA512Transform(Context, @(Context.Data[0]), BlockCount); + + for I := 0 to 7 do + begin + Digest[I] := (Context.State[0] shr (56 - I * 8)) and $000000FF; + Digest[I + 8] := (Context.State[1] shr (56 - I * 8)) and $000000FF; + Digest[I + 16] := (Context.State[2] shr (56 - I * 8)) and $000000FF; + Digest[I + 24] := (Context.State[3] shr (56 - I * 8)) and $000000FF; + Digest[I + 32] := (Context.State[4] shr (56 - I * 8)) and $000000FF; + Digest[I + 40] := (Context.State[5] shr (56 - I * 8)) and $000000FF; + Digest[I + 48] := (Context.State[6] shr (56 - I * 8)) and $000000FF; + Digest[I + 56] := (Context.State[7] shr (56 - I * 8)) and $000000FF; + end; +end; + +// ݿ SHA224 +function SHA224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, Input, ByteLength); + SHA224Final(Context, Result); +end; + +// ݿ SHA256 +function SHA256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, Input, ByteLength); + SHA256Final(Context, Result); +end; + +// ݿ SHA384 +function SHA384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, Input, ByteLength); + SHA384Final(Context, Result); +end; + +// ݿ SHA512 +function SHA512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, Input, ByteLength); + SHA512Final(Context, Result); +end; + +// ݿ SHA224 +function SHA224Buffer(const Buffer; Count: Cardinal): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(Buffer), Count); + SHA224Final(Context, Result); +end; + +// ݿ SHA256 +function SHA256Buffer(const Buffer; Count: Cardinal): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(Buffer), Count); + SHA256Final(Context, Result); +end; + +// ݿ SHA384 +function SHA384Buffer(const Buffer; Count: Cardinal): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(Buffer), Count); + SHA384Final(Context, Result); +end; + +// ݿ SHA512 +function SHA512Buffer(const Buffer; Count: Cardinal): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(Buffer), Count); + SHA512Final(Context, Result); +end; + +// ֽ SHA224 +function SHA224Bytes(Data: TBytes): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA224Final(Context, Result); +end; + +// ֽ SHA256 +function SHA256Bytes(Data: TBytes): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA256Final(Context, Result); +end; + +// ֽ SHA384 +function SHA384Bytes(Data: TBytes): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA384Final(Context, Result); +end; + +// ֽ SHA512 +function SHA512Bytes(Data: TBytes): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA512Final(Context, Result); +end; + +// String ݽ SHA224 +function SHA224String(const Str: string): TCnSHA224Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA224StringA(AStr); +end; + +// String ݽ SHA256 +function SHA256String(const Str: string): TCnSHA256Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA256StringA(AStr); +end; + +// String ݽ SHA384 +function SHA384String(const Str: string): TCnSHA384Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA384StringA(AStr); +end; + +// String ݽ SHA512 +function SHA512String(const Str: string): TCnSHA512Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA512StringA(AStr); +end; + +// UnicodeString ݽֱӵ SHA224 㣬ת +{$IFDEF UNICODE} +function SHA224UnicodeString(const Str: string): TCnSHA224Digest; +{$ELSE} +function SHA224UnicodeString(const Str: WideString): TCnSHA224Digest; +{$ENDIF} +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA224Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA256 㣬ת +{$IFDEF UNICODE} +function SHA256UnicodeString(const Str: string): TCnSHA256Digest; +{$ELSE} +function SHA256UnicodeString(const Str: WideString): TCnSHA256Digest; +{$ENDIF} +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA256Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA384 㣬ת +{$IFDEF UNICODE} +function SHA384UnicodeString(const Str: string): TCnSHA384Digest; +{$ELSE} +function SHA384UnicodeString(const Str: WideString): TCnSHA384Digest; +{$ENDIF} +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA384Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHA512 㣬ת +{$IFDEF UNICODE} +function SHA512UnicodeString(const Str: string): TCnSHA512Digest; +{$ELSE} +function SHA512UnicodeString(const Str: WideString): TCnSHA512Digest; +{$ENDIF} +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA512Final(Context, Result); +end; + +// AnsiString ݽ SHA224 +function SHA224StringA(const Str: AnsiString): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224Update(Context, PAnsiChar(Str), Length(Str)); + SHA224Final(Context, Result); +end; + +// WideString ݽ SHA224 +function SHA224StringW(const Str: WideString): TCnSHA224Digest; +var + Context: TCnSHA224Context; +begin + SHA224Init(Context); + SHA224UpdateW(Context, PWideChar(Str), Length(Str)); + SHA224Final(Context, Result); +end; + +// AnsiString ݽ SHA256 +function SHA256StringA(const Str: AnsiString): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256Update(Context, PAnsiChar(Str), Length(Str)); + SHA256Final(Context, Result); +end; + +// WideString ݽ SHA256 +function SHA256StringW(const Str: WideString): TCnSHA256Digest; +var + Context: TCnSHA256Context; +begin + SHA256Init(Context); + SHA256UpdateW(Context, PWideChar(Str), Length(Str)); + SHA256Final(Context, Result); +end; + +// AnsiString ݽ SHA384 +function SHA384StringA(const Str: AnsiString): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384Update(Context, PAnsiChar(Str), Length(Str)); + SHA384Final(Context, Result); +end; + +// WideString ݽ SHA384 +function SHA384StringW(const Str: WideString): TCnSHA384Digest; +var + Context: TCnSHA384Context; +begin + SHA384Init(Context); + SHA384UpdateW(Context, PWideChar(Str), Length(Str)); + SHA384Final(Context, Result); +end; + +// AnsiString ݽ SHA512 +function SHA512StringA(const Str: AnsiString): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512Update(Context, PAnsiChar(Str), Length(Str)); + SHA512Final(Context, Result); +end; + +// WideString ݽ SHA512 +function SHA512StringW(const Str: WideString): TCnSHA512Digest; +var + Context: TCnSHA512Context; +begin + SHA512Init(Context); + SHA512UpdateW(Context, PWideChar(Str), Length(Str)); + SHA512Final(Context, Result); +end; + +function InternalSHAStream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHAGeneralDigest; SHA2Type: TSHA2Type; CallBack: TCnSHACalcProgressFunc = nil): Boolean; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + + Context224: TCnSHA224Context; + Context256: TCnSHA256Context; + Context384: TCnSHA384Context; + Context512: TCnSHA512Context; + Dig224: TCnSHA224Digest; + Dig256: TCnSHA256Digest; + Dig384: TCnSHA384Digest; + Dig512: TCnSHA512Digest; + + procedure _SHAInit; + begin + case SHA2Type of + stSHA2_224: + SHA224Init(Context224); + stSHA2_256: + SHA256Init(Context256); + stSHA2_384: + SHA384Init(Context384); + stSHA2_512: + SHA512Init(Context512); + end; + end; + + procedure _SHAUpdate; + begin + case SHA2Type of + stSHA2_224: + SHA224Update(Context224, Buf, ReadBytes); + stSHA2_256: + SHA256Update(Context256, Buf, ReadBytes); + stSHA2_384: + SHA384Update(Context384, Buf, ReadBytes); + stSHA2_512: + SHA512Update(Context512, Buf, ReadBytes); + end; + end; + + procedure _SHAFinal; + begin + case SHA2Type of + stSHA2_224: + SHA224Final(Context224, Dig224); + stSHA2_256: + SHA256Final(Context256, Dig256); + stSHA2_384: + SHA384Final(Context384, Dig384); + stSHA2_512: + SHA512Final(Context512, Dig512); + end; + end; + + procedure _CopyResult; + begin + case SHA2Type of + stSHA2_224: + Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); + stSHA2_256: + Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); + stSHA2_384: + Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); + stSHA2_512: + Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); + end; + end; + +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + _SHAInit; + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + _SHAUpdate; + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + _SHAFinal; + _CopyResult; + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA224 +function SHA224Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA224Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); +end; + +// ָ SHA256 +function SHA256Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA256Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); +end; + +// ָ SHA384 +function SHA384Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA384Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); +end; + +// ָ SHA512 +function SHA512Stream(Stream: TStream; CallBack: TCnSHACalcProgressFunc = nil): + TCnSHA512Digest; +var + Dig: TCnSHAGeneralDigest; +begin + InternalSHAStream(Stream, 4096 * 1024, Dig, stSHA2_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); +end; + +function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} +var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec: Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, + OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then + Exit; + try + if not GetFileInformationByHandle(H, Info) then + Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} +end; + +function InternalSHAFile(const FileName: string; SHA2Type: TSHA2Type; + CallBack: TCnSHACalcProgressFunc): TCnSHAGeneralDigest; +var + Context224: TCnSHA224Context; + Context256: TCnSHA256Context; + Context384: TCnSHA384Context; + Context512: TCnSHA512Context; + Dig224: TCnSHA224Digest; + Dig256: TCnSHA256Digest; + Dig384: TCnSHA384Digest; + Dig512: TCnSHA512Digest; + +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + procedure _SHAInit; + begin + case SHA2Type of + stSHA2_224: + SHA224Init(Context224); + stSHA2_256: + SHA256Init(Context256); + stSHA2_384: + SHA384Init(Context384); + stSHA2_512: + SHA512Init(Context512); + end; + end; + +{$IFDEF MSWINDOWS} + procedure _SHAUpdate; + begin + case SHA2Type of + stSHA2_224: + SHA224Update(Context224, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_256: + SHA256Update(Context256, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_384: + SHA384Update(Context384, ViewPointer, GetFileSize(FileHandle, nil)); + stSHA2_512: + SHA512Update(Context512, ViewPointer, GetFileSize(FileHandle, nil)); + end; + end; +{$ENDIF} + + procedure _SHAFinal; + begin + case SHA2Type of + stSHA2_224: + SHA224Final(Context224, Dig224); + stSHA2_256: + SHA256Final(Context256, Dig256); + stSHA2_384: + SHA384Final(Context384, Dig384); + stSHA2_512: + SHA512Final(Context512, Dig512); + end; + end; + + procedure _CopyResult(var D: TCnSHAGeneralDigest); + begin + case SHA2Type of + stSHA2_224: + Move(Dig224[0], D[0], SizeOf(TCnSHA224Digest)); + stSHA2_256: + Move(Dig256[0], D[0], SizeOf(TCnSHA256Digest)); + stSHA2_384: + Move(Dig384[0], D[0], SizeOf(TCnSHA384Digest)); + stSHA2_512: + Move(Dig512[0], D[0], SizeOf(TCnSHA512Digest)); + end; + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHAStream(Stream, 4096 * 1024, Result, SHA2Type, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + _SHAInit; + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + _SHAUpdate; + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + _SHAFinal; + _CopyResult(Result); +{$ENDIF} + end; +end; + +// ָļݽ SHA224 +function SHA224File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA224Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA224Digest)); +end; + +// ָļݽ SHA256 +function SHA256File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA256Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA256Digest)); +end; + +// ָļݽ SHA384 +function SHA384File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA384Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA384Digest)); +end; + +// ָļݽ SHA512 +function SHA512File(const FileName: string; CallBack: TCnSHACalcProgressFunc): + TCnSHA512Digest; +var + Dig: TCnSHAGeneralDigest; +begin + Dig := InternalSHAFile(FileName, stSHA2_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA512Digest)); +end; + +// ʮƸʽ SHA224 Ӵֵ +function SHA224Print(const Digest: TCnSHA224Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA224Digest)); +end; + +// ʮƸʽ SHA256 Ӵֵ +function SHA256Print(const Digest: TCnSHA256Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA256Digest)); +end; + +// ʮƸʽ SHA384 Ӵֵ +function SHA384Print(const Digest: TCnSHA384Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA384Digest)); +end; + +// ʮƸʽ SHA512 Ӵֵ +function SHA512Print(const Digest: TCnSHA512Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA512Digest)); +end; + +// Ƚ SHA224 ӴֵǷ +function SHA224Match(const D1, D2: TCnSHA224Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 28) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA256 ӴֵǷ +function SHA256Match(const D1, D2: TCnSHA256Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 32) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA384 ӴֵǷ +function SHA384Match(const D1, D2: TCnSHA384Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 48) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// Ƚ SHA512 ӴֵǷ +function SHA512Match(const D1, D2: TCnSHA512Digest): Boolean; +var + I: Integer; +begin + I := 0; + Result := True; + while Result and (I < 64) do + begin + Result := D1[I] = D2[I]; + Inc(I); + end; +end; + +// SHA224 Ӵֵת string +function SHA224DigestToStr(const Digest: TCnSHA224Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA224Digest)); +end; + +// SHA256 Ӵֵת string +function SHA256DigestToStr(const Digest: TCnSHA256Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA256Digest)); +end; + +// SHA384 Ӵֵת string +function SHA384DigestToStr(const Digest: TCnSHA384Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA384Digest)); +end; + +// SHA512 Ӵֵת string +function SHA512DigestToStr(const Digest: TCnSHA512Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA512Digest)); +end; + +procedure SHA224HmacInit(var Context: TCnSHA224Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA224Digest; +begin + if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA224Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA224Init(Context); + SHA224Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA224HmacUpdate(var Context: TCnSHA224Context; Input: PAnsiChar; Length: + Cardinal); +begin + SHA224Update(Context, Input, Length); +end; + +procedure SHA224HmacFinal(var Context: TCnSHA224Context; var Output: TCnSHA224Digest); +var + Len: Integer; + TmpBuf: TCnSHA224Digest; +begin + Len := HMAC_SHA2_224_OUTPUT_LENGTH_BYTE; + SHA224Final(Context, TmpBuf); + SHA224Init(Context); + SHA224Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); + SHA224Update(Context, @(TmpBuf[0]), Len); + SHA224Final(Context, Output); +end; + +procedure SHA256HmacInit(var Context: TCnSHA256Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA256Digest; +begin + if KeyLength > HMAC_SHA2_224_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA256Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_224_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA256Init(Context); + SHA256Update(Context, @(Context.Ipad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA256HmacUpdate(var Context: TCnSHA256Context; Input: PAnsiChar; Length: + Cardinal); +begin + SHA256Update(Context, Input, Length); +end; + +procedure SHA256HmacFinal(var Context: TCnSHA256Context; var Output: TCnSHA256Digest); +var + Len: Integer; + TmpBuf: TCnSHA256Digest; +begin + Len := HMAC_SHA2_256_OUTPUT_LENGTH_BYTE; + SHA256Final(Context, TmpBuf); + SHA256Init(Context); + SHA256Update(Context, @(Context.Opad[0]), HMAC_SHA2_224_256_BLOCK_SIZE_BYTE); + SHA256Update(Context, @(TmpBuf[0]), Len); + SHA256Final(Context, Output); +end; + +procedure SHA224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA224Digest); +var + Context: TCnSHA224Context; +begin + SHA224HmacInit(Context, Key, KeyByteLength); + SHA224HmacUpdate(Context, Input, ByteLength); + SHA224HmacFinal(Context, Output); +end; + +procedure SHA256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA256Digest); +var + Context: TCnSHA256Context; +begin + SHA256HmacInit(Context, Key, KeyByteLength); + SHA256HmacUpdate(Context, Input, ByteLength); + SHA256HmacFinal(Context, Output); +end; + +procedure SHA384HmacInit(var Context: TCnSHA384Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA384Digest; +begin + if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA384Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA384Init(Context); + SHA384Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA384HmacUpdate(var Context: TCnSHA384Context; Input: PAnsiChar; + Length: Cardinal); +begin + SHA384Update(Context, Input, Length); +end; + +procedure SHA384HmacFinal(var Context: TCnSHA384Context; var Output: TCnSHA384Digest); +var + Len: Integer; + TmpBuf: TCnSHA384Digest; +begin + Len := HMAC_SHA2_384_OUTPUT_LENGTH_BYTE; + SHA384Final(Context, TmpBuf); + SHA384Init(Context); + SHA384Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); + SHA384Update(Context, @(TmpBuf[0]), Len); + SHA384Final(Context, Output); +end; + +procedure SHA384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA384Digest); +var + Context: TCnSHA384Context; +begin + SHA384HmacInit(Context, Key, KeyByteLength); + SHA384HmacUpdate(Context, Input, ByteLength); + SHA384HmacFinal(Context, Output); +end; + +procedure SHA512HmacInit(var Context: TCnSHA512Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA512Digest; +begin + if KeyLength > HMAC_SHA2_384_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA512Buffer(Key, KeyLength); + KeyLength := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA2_384_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA512Init(Context); + SHA512Update(Context, @(Context.Ipad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA512HmacUpdate(var Context: TCnSHA512Context; Input: PAnsiChar; + Length: Cardinal); +begin + SHA512Update(Context, Input, Length); +end; + +procedure SHA512HmacFinal(var Context: TCnSHA512Context; var Output: TCnSHA512Digest); +var + Len: Integer; + TmpBuf: TCnSHA512Digest; +begin + Len := HMAC_SHA2_512_OUTPUT_LENGTH_BYTE; + SHA512Final(Context, TmpBuf); + SHA512Init(Context); + SHA512Update(Context, @(Context.Opad[0]), HMAC_SHA2_384_512_BLOCK_SIZE_BYTE); + SHA512Update(Context, @(TmpBuf[0]), Len); + SHA512Final(Context, Output); +end; + +procedure SHA512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA512Digest); +var + Context: TCnSHA512Context; +begin + SHA512HmacInit(Context, Key, KeyByteLength); + SHA512HmacUpdate(Context, Input, ByteLength); + SHA512HmacFinal(Context, Output); +end; + +end. diff --git a/CnPack/Crypto/CnSHA3.dcu b/CnPack/Crypto/CnSHA3.dcu new file mode 100644 index 0000000000000000000000000000000000000000..ab48000027067f61ba76ba27ee6468164f3d3a11 GIT binary patch literal 31943 zcmeHw3w%`7)$g7&=S*gXBn%iRAoxuvL5PqK2%-2uCy#+dlMs>_UWyo#$q>u~^HA|K z8X9N`V=T1N3I#9p>R0jc>kSnPUhM@60*V%_w$N$|tyHYw7i!c{k=*~<`@H6nkSO}Q zzu)~v4||=p*Iuu^*4q2LpuoyTA9#SVZu}ViBwKb(Np5EP#Vfi${xP%Nu*{iVQ&d`Z zS6XFF*=J2lZ<7c?1Zm4k>pjg&Z)4@QlI8Ucfocp6I*Wbza|3ntm9;g0`0k>z3OQ?e zL*O4{Kawkyyqbn-Q~z?$3;(FFXP4HMSJsqPecHW3s));~t*r`_)=XdV(w!BKqRg85 z%IqbjbxrqmU0GqPZ>X!R2~Kz^{D zE8-wC5De69d82+uh0V`3Skf|~BWU+5uBvLRUsCtM9n1Cy+OVwv;)O&5c z-j^6m^yHS-lvf32k~6E8ll~QUUuIoh>GC@!-<_W52|7vw4f%nZV8arw)nHG~@*3W+ z|2)B9+()-R4hD3lF}SVr)~AB9_rA&oZmvDEzP>V86Da3rvahZ&@H{30n)~XO zt4l$Jl+^#0_atD?FDz76CAYL?Hdt856wKluLS z3Wrc0d0e%|Rv2`q>F2X=fA4<;iKVZWJpaI{Um0gV*gs`&(4~{6Wg{ON0-K+{^6$`9 zxJ&4jSd#lt(3xFZy$q5O+;NK^n^#tzs5&9Ls^*!Q z+RQ^*EvrmJQ(k*7X%oCcOH*HML1R@zB~3;9!Op8I;(Q_#-z!-9bj66Q1&ebt3v=?l zi)ZHHkG#T}vx^HdeR;DB58eB20_^5)Ay6W^KvwCIPrTIeiob&903=RfV`TD z+Pdme@>JGxq2t2A*X|7t$gZlb4+z99$CgbAx=bSH73cZ9+eyF>j?MJ>iu1DkKJVf} zG9>@mHRu}7yJqHR&RSgJo#Xcw`tmaK7nfvb7XEwP`-g&q3?mClmn}o0yz{pov;-51 zGG_^!W*6o!;4%`>KesY)@9YXv_;=q~^8H`}=UtFl#I4^+nha14qB{JK2a=x)4)oVl zn+HBNWseW8M7=AmZ}8UD)z-b{{>jF&a(i}7A?&{=Kq(ccW(=(Y74hncD46eG929iq zls1(5YI6hk-SFJVxS*4#8b5D%f8@Ggyc)0^ePHVHA;Cn%Zf)Iio(eGWz^<#T!31@b zi1%fWC9dX5WY^ZzH}EJLQj%T66$~@Hva-Sx9Ikamd5^lwGStO+C1ZjL%lGaGBlKoA)C=yksDNNJO2GB%f`IO`i|t4G#58JmxZH&7YV z1WM9T&|9En9R;NX%BG_D{0o#_M`4Zy%9-l$kwD+_Wt6V-QxXa?=Zhj*lDE(cqJ@kN zM2|aVV2KaqvS4wRf97JNFAjN-GJxw`JlkKGQ-UFgr%5STa9~G?FH=ODKu<}zQZsMy zY`?F_?^7d@N2Q>duF)V4d!q5EG;lzVGp@JNp|7E8)7U7@V}+1a;n(==^vV=PnB zD4N*Gq!3{NR^lr$$~=UYBUA(*eayl;-&PANdY}ZD+1UkK_u-*t_%70>qNPn(L&VQVFMI!m_98Ozvo zSF(jDlDgbB>}Ro~!O8R!Wt$xB(pXEo#Jb0cyz$kQ*3{ERf*2&kORSuYj#JADh7@{l+S6`JF|{Y$mV9cDxh+L#D~`A=KD5(!yQQpb083U}bX(FYm_;7CMFo-` zD;sC0m{GUJtW}N{m&_@sN`T4yPm^7uDAK|!E>M8Boldc&A%|^HdE*z-d8urillc0V zm19pzhMbpTaK?4&vPSZQvm=?W|0agQD%%OSHLv_W5^=0-94|J4=R9KiuikhL15dh; zG4m9Dtl=WT8C@!82WiW%Qi$(UlEq!lUdXV9JASlHn2s@?j>Oy1;3Wr~yr^rPF|Ds!XH2_HT4zktv|d|z ze#RxV&W)ut>P8>62Ib|^8jLipH~zTd%^rmF(I^ zzFOJ(?s1iS#x$LK)4WhSanJ1&_uhRjxWnf<_g_qZE{(Y7_lbM&UKiZqb)CEWhv&

NA(3P9!?JiueiT3|zuV96ev0!$^2X$c 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 IRjl;?0`Q@bKL7v# literal 0 HcmV?d00001 diff --git a/CnPack/Crypto/CnSHA3.pas b/CnPack/Crypto/CnSHA3.pas new file mode 100644 index 0000000..3e0ade0 --- /dev/null +++ b/CnPack/Crypto/CnSHA3.pas @@ -0,0 +1,2700 @@ +{******************************************************************************} +{ CnPack For Delphi/C++Builder } +{ йԼĿԴ } +{ (C)Copyright 2001-2025 CnPack } +{ ------------------------------------ } +{ } +{ ǿԴ CnPack ķЭ } +{ ĺ·һ } +{ } +{ һĿϣãûκεû } +{ ʺضĿĶĵϸ CnPack Э顣 } +{ } +{ ӦѾͿһյһ CnPack Эĸ } +{ ûУɷǵվ } +{ } +{ վַhttps://www.cnpack.org } +{ ʼmaster@cnpack.org } +{ } +{******************************************************************************} + +unit CnSHA3; +{* |

+================================================================================
+* ƣ
+* ԪƣSHA3 Ӵ㷨ʵֵԪ
+* ԪߣCnPack  (master@cnpack.org)
+*           / Keccak C  Pascal ֲ䲿ֹܡ
+*     עԪʵ SHA3 ϵӴ㷨Ӧ HMAC 㷨 SHA3-224/256/384/512
+*           ɱ䳤ժҪ SHAKE128/SHAKE256ȡ
+*           SHA3 淶 NIST.FIPS.202
+*           SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+*           жⶨ Bit  Byte ת
+*           ֮ Bit ܹ 8 ʱÿ 8  Bit λþһֽڣֽڼ˳򱣳ֲ䡣
+*
+* ƽ̨PWinXP + Delphi 5.0
+* ݲԣPWinXP/7 + Delphi 5/6
+*   õԪеַϱػʽ
+* ޸ļ¼2023.08.02 V1.4
+*                SHAKE128/SHAKE256 Ŀɱ䳤ժҪļ
+*           2022.04.26 V1.3
+*               ޸ LongWord  Integer ַת֧ MacOS64
+*           2019.12.12 V1.2
+*               ֧ TBytes
+*           2019.04.15 V1.1
+*               ֧ Win32/Win64/MacOS
+*           2017.11.10 V1.0
+*               Ԫ
+================================================================================
+|
} + +interface + +{$I CnPack.inc} + +uses + SysUtils, Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, CnNative, CnConsts; + +const + CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH = 32; + {* SHAKE128 ĬӴսֽڳ} + + CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH = 64; + {* SHAKE256 ĬӴսֽڳ} + +type + PCnSHA3GeneralDigest = ^TCnSHA3GeneralDigest; + TCnSHA3GeneralDigest = array[0..63] of Byte; + {* SHA3 ϵͨõӴս 64 ֽΪ׼} + + PCnSHA3_224Digest = ^TCnSHA3_224Digest; + TCnSHA3_224Digest = array[0..27] of Byte; + {* SHA3_224 Ӵս28 ֽ} + + PCnSHA3_256Digest = ^TCnSHA3_256Digest; + TCnSHA3_256Digest = array[0..31] of Byte; + {* SHA3_256 Ӵս32 ֽ} + + PCnSHA3_384Digest = ^TCnSHA3_384Digest; + TCnSHA3_384Digest = array[0..47] of Byte; + {* SHA3_384 Ӵս48 ֽ} + + PCnSHA3_512Digest = ^TCnSHA3_512Digest; + TCnSHA3_512Digest = array[0..63] of Byte; + {* SHA3_512 Ӵս64 ֽ} + + TCnSHA3Context = packed record + {* SHA3 ϵͨõĽṹ} + State: array[0..24] of Int64; + Index: Cardinal; + DigestLen: Cardinal; + Round: Cardinal; + BlockLen: Cardinal; + Block: array[0..255] of Byte; + Ipad: array[0..143] of Byte; {!< HMAC: inner padding } + Opad: array[0..143] of Byte; {!< HMAC: outer padding } + end; + + TCnSHA3CalcProgressFunc = procedure(ATotal, AProgress: Int64; var Cancel: + Boolean) of object; + {* SHA3 ϵͨõļȻص¼} + +function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; +{* ݿ SHA3_224 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; +{* ݿ SHA3_256 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; +{* ݿ SHA3_384 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; +{* ݿ SHA3_512 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; +{* ݿ SHA3_224 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; +{* ݿ SHA3_256 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; +{* ݿ SHA3_384 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; +{* ݿ SHA3_512 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128Buffer(const Buffer; Count: Cardinal; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256Buffer(const Buffer; Count: Cardinal; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ݿӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; +{* ֽ SHA3_224 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; +{* ֽ SHA3_256 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; +{* ֽ SHA3_384 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; +{* ֽ SHA3_512 㡣 + + + Data: TBytes - ֽ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ֽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + + + Data: TBytes - ֽ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* ֽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս + + + Data: TBytes - ֽ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224String(const Str: string): TCnSHA3_224Digest; +{* String ݽ SHA3_224 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256String(const Str: string): TCnSHA3_256Digest; +{* String ݽ SHA3_256 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384String(const Str: string): TCnSHA3_384Digest; +{* String ݽ SHA3_384 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512String(const Str: string): TCnSHA3_512Digest; +{* String ݽ SHA3_512 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* String ݽӴճȿɱ SHAKE128 㣬سΪ DigestByteLength ֽΪӴս + ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 + + + const Str: string - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256String(const Str: string; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* String ݽӴճȿɱ SHAKE256 㣬سΪ DigestByteLength ֽΪӴս + ע D2009 ϰ汾 string Ϊ UnicodeStringлὫǿת AnsiString м㡣 + + + const Str: string - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; +{* AnsiString ݽ SHA3_224 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; +{* WideString ݽ SHA3_224 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; +{* AnsiString ݽ SHA3_256 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; +{* WideStringݽ SHA3_256 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; +{* AnsiString ݽ SHA3_384 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; +{* WideString ݽ SHA3_384 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; +{* AnsiString ݽ SHA3_512 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; +{* WideString ݽ SHA512 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128StringA(const Str: AnsiString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const Str: AnsiString - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE128StringW(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* WideString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* AnsiString ݽӴճȿɱֱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const Str: AnsiString - ַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* WideString ݽӴճȿɱֱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$IFDEF UNICODE} + +function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; +{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; +{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; +{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; +{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128UnicodeString(const Str: string; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: string - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256UnicodeString(const Str: string; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: string - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$ELSE} + +function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; +{* UnicodeString ݽֱӵ SHA3_224 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; +{* UnicodeString ݽֱӵ SHA3_256 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; +{* UnicodeString ݽֱӵ SHA3_384 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; +{* UnicodeString ݽֱӵ SHA3_512 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128UnicodeString(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE128 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256UnicodeString(const Str: WideString; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH): TBytes; +{* UnicodeString ݽӴճȿɱֱ SHAKE256 㣬ֱӼڲ UTF16 ݣת + سΪ DigestByteLength ֽΪӴս + + + const Str: WideString - Ŀַ + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵTBytes - SHAKE256 Ӵֵ +} + +{$ENDIF} + +function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_224Digest; +{* ָļݽ SHA3_224 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_224Digest; +{* ָݽ SHA3_224 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_224Digest - ص SHA3_224 Ӵֵ +} + +function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_256Digest; +{* ָļݽ SHA3_256 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_256Digest; +{* ָݽ SHA3_256 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_256Digest - ص SHA3_256 Ӵֵ +} + +function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_384Digest; +{* ָļݽ SHA3_384 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_384Digest; +{* ָݽ SHA3_384 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_384Digest - ص SHA3_384 Ӵֵ +} + +function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc = + nil): TCnSHA3_512Digest; +{* ָļݽ SHA3_512 㡣 + + + const FileName: string - ļ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc = nil): + TCnSHA3_512Digest; +{* ָݽ SHA3_512 㡣 + + + Stream: TStream - + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTCnSHA3_512Digest - ص SHA3_512 Ӵֵ +} + +function SHAKE128File(const FileName: string; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָļݽӴճȿɱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + const FileName: string - ļ + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE128Ӵֵ +} + +function SHAKE128Stream(Stream: TStream; + DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָӴճȿɱ SHAKE128 㣬 + سΪ DigestByteLength ֽΪӴս + + + Stream: TStream - + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE128 Ӵֵ +} + +function SHAKE256File(const FileName: string; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָļݽӴճȿɱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + + + const FileName: string - ļ + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE256 Ӵֵ +} + +function SHAKE256Stream(Stream: TStream; + DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH; + CallBack: TCnSHA3CalcProgressFunc = nil): TBytes; +{* ָӴճȿɱ SHAKE256 㣬 + سΪ DigestByteLength ֽΪӴս + + + Stream: TStream - + DigestByteLength: Cardinal - Ӵսֽڳ + CallBack: TCnSHA3CalcProgressFunc - ȻصĬΪ + + ֵTBytes - SHAKE256 Ӵֵ +} + +// ⲿݽɢ SHA3_224 㣬SHA3_224Update ɶα + +procedure SHA3_224Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_224 ģ׼ SHA3_224 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_224 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); +{* ּ㣬 SHA3_224 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_256 㣬SHA3_256Update ɶα + +procedure SHA3_256Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_256 ģ׼ SHA3_256 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); +{* ּ㣬 SHA3_256 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_384 㣬SHA3_384Update ɶα + +procedure SHA3_384Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_384 ģ׼ SHA3_384 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_384 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); +{* ּ㣬 SHA3_384 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHA3_512 㣬SHA3_512Update ɶα + +procedure SHA3_512Init(var Context: TCnSHA3Context); +{* ʼһ SHA3_512 ģ׼ SHA3_512 + + + var Context: TCnSHA3Context - ʼͨ SHA3 + + ֵޣ +} + +procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHA3_512 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); +{* ּ㣬 SHA3_512 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + var Digest: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα + +procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE128_DEF_DIGEST_BYTE_LENGTH); +{* ʼһ SHAKE128 ģ׼ SHAKE128 + DigestByteLength ΪӴյֽڳȡ + + + var Context: TCnSHA3Context - ʼͨ SHA3 + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵޣ +} + +procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHAKE128 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); +{* ּ㣬 SHAKE128 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + out Digest: TBytes - ص SHAKE128 Ӵֵ + + ֵޣ +} + +// ⲿݽɢ SHAKE128 㣬SHAKE128Update ɶα + +procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal = CN_SHAKE256_DEF_DIGEST_BYTE_LENGTH); +{* ʼһ SHAKE256 ģ׼ SHAKE256 + DigestByteLength ΪӴյֽڳȡ + + + var Context: TCnSHA3Context - ʼͨ SHA3 + DigestByteLength: Cardinal - Ӵսֽڳ + + ֵޣ +} + +procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SHAKE256 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSHA3Context - ͨ SHA3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); +{* ּ㣬 SHAKE256 Digest С + + + var Context: TCnSHA3Context - ͨ SHA3 + out Digest: TBytes - ص SHAKE256 Ӵֵ + + ֵޣ +} + +function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; +{* ʮƸʽ SHA3_224 Ӵֵ + + + const Digest: TCnSHA3_224Digest - ָ SHA3_224 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; +{* ʮƸʽ SHA3_256 Ӵֵ + + + const Digest: TCnSHA3_256Digest - ָ SHA3_256 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; +{* ʮƸʽ SHA3_384 Ӵֵ + + const Digest: TCnSHA3_384Digest - ָ SHA3_384 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; +{* ʮƸʽ SHA3_512 Ӵֵ + + + const Digest: TCnSHA3_512Digest - ָ SHA3_512 Ӵֵ + + ֵstring - ʮַ +} + +function SHAKE128Print(const Digest: TBytes): string; +{* ʮƸʽ SHAKE128 Ӵֵ + + + const Digest: TBytes - ָ SHAKE128 Ӵֵ + + ֵstring - ʮַ +} + +function SHAKE256Print(const Digest: TBytes): string; +{* ʮƸʽ SHAKE256 Ӵֵ + + + const Digest: TBytes - ָ SHAKE128 Ӵֵ + + ֵstring - ʮַ +} + +function SHA3_224Match(const D1: TCnSHA3_224Digest; const D2: TCnSHA3_224Digest): Boolean; +{* Ƚ SHA3_224 ӴֵǷȡ + + + const D1: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵһ + const D2: TCnSHA3_224Digest - Ƚϵ SHA3_224 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_256Match(const D1: TCnSHA3_256Digest; const D2: TCnSHA3_256Digest): Boolean; +{* Ƚ SHA3_256 ӴֵǷȡ + + + const D1: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵһ + const D2: TCnSHA3_256Digest - Ƚϵ SHA3_256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_384Match(const D1: TCnSHA3_384Digest; const D2: TCnSHA3_384Digest): Boolean; +{* Ƚ SHA3_384 ӴֵǷȡ + + + const D1: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵһ + const D2: TCnSHA3_384Digest - Ƚϵ SHA3_384 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_512Match(const D1: TCnSHA3_512Digest; const D2: TCnSHA3_512Digest): Boolean; +{* Ƚ SHA3_512 ӴֵǷȡ + + + const D1: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵһ + const D2: TCnSHA3_512Digest - Ƚϵ SHA3_512 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHAKE128Match(const D1: TBytes; const D2: TBytes): Boolean; +{* Ƚ SHAKE128 ӴֵǷȡ + + + const D1: TBytes - Ƚϵ SHAKE128 Ӵֵһ + const D2: TBytes - Ƚϵ SHAKE128 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHAKE256Match(const D1: TBytes; const D2: TBytes): Boolean; +{* Ƚ SHAKE256 ӴֵǷȡ + + + const D1: TBytes - Ƚϵ SHAKE256 Ӵֵһ + const D2: TBytes - Ƚϵ SHAKE256 Ӵֵ + + ֵBoolean - Ƿ +} + +function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; +{* SHA3_224 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_224Digest - ת SHA3_224 Ӵֵ + + ֵstring - صַ +} + +function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; +{* SHA3_256 Ӵֱֵת stringÿֽڶӦһַ + |
+   Digest: TSHA3_256Digest   - Ҫ
+ |
+ + + const Digest: TCnSHA3_256Digest - ת SHA3_256 Ӵֵ + + ֵstring - صַ +} + +function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; +{* SHA3_384 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_384Digest - ת SHA3_384 Ӵֵ + + ֵstring - صַ +} + +function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; +{* SHA3_512 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSHA3_512Digest - ת SHA3_512 Ӵֵ + + ֵstring - صַ +} + +function SHAKE128DigestToStr(const Digest: TBytes): string; +{* SHAKE128 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TBytes - ת SHAKE128 Ӵֵ + + ֵstring - صַ +} + +function SHAKE256DigestToStr(const Digest: TBytes): string; +{* SHAKE256 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TBytes - ת SHAKE256 Ӵֵ + + ֵstring - صַ +} + +procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_224Digest); +{* SHA3_224 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_224 Կݿַ + KeyByteLength: Integer - SHA3_224 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_224Digest - ص SHA3_224 Ӵֵ + + ֵޣ +} + +procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_256Digest); +{* SHA3_256 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_256 Կݿַ + KeyByteLength: Integer - SHA3_256 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_256Digest - ص SHA3_256 Ӵֵ + + ֵޣ +} + +procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_384Digest); +{* SHA3_384 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_384 Կݿַ + KeyByteLength: Integer - SHA3_384 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_384Digest - ص SHA3_384 Ӵֵ + + ֵޣ +} + +procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_512Digest); +{* SHA3_512 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SHA3_512 Կݿַ + KeyByteLength: Integer - SHA3_512 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSHA3_512Digest - ص SHA3_512 Ӵֵ + + ֵޣ +} + +implementation + +type + TSHA3Type = (stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512, stSHAKE128, stSHAKE256); + +const + MAX_FILE_SIZE = 512 * 1024 * 1024; + STREAM_BUF_SIZE = 4096 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + SHA3_ROUNDS = 24; + SHA3_STATE_LEN = 25; + + SHA3_224_OUTPUT_LENGTH_BYTE = 28; + SHA3_256_OUTPUT_LENGTH_BYTE = 32; + SHA3_384_OUTPUT_LENGTH_BYTE = 48; + SHA3_512_OUTPUT_LENGTH_BYTE = 64; + + SHA3_224_BLOCK_SIZE_BYTE = 144; + SHA3_256_BLOCK_SIZE_BYTE = 136; + SHA3_384_BLOCK_SIZE_BYTE = 104; + SHA3_512_BLOCK_SIZE_BYTE = 72; + + SHAKE128_BLOCK_SIZE_BYTE = 168; + SHAKE256_BLOCK_SIZE_BYTE = 136; + + HMAC_SHA3_224_BLOCK_SIZE_BYTE = SHA3_224_BLOCK_SIZE_BYTE; + HMAC_SHA3_256_BLOCK_SIZE_BYTE = SHA3_256_BLOCK_SIZE_BYTE; + HMAC_SHA3_384_BLOCK_SIZE_BYTE = SHA3_384_BLOCK_SIZE_BYTE; + HMAC_SHA3_512_BLOCK_SIZE_BYTE = SHA3_512_BLOCK_SIZE_BYTE; + + HMAC_SHA3_224_OUTPUT_LENGTH_BYTE = SHA3_224_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_256_OUTPUT_LENGTH_BYTE = SHA3_256_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_384_OUTPUT_LENGTH_BYTE = SHA3_384_OUTPUT_LENGTH_BYTE; + HMAC_SHA3_512_OUTPUT_LENGTH_BYTE = SHA3_512_OUTPUT_LENGTH_BYTE; + + KECCAKF_ROUND_CONSTS: array[0..23] of TUInt64 = ( + $0000000000000001, $0000000000008082, $800000000000808A, + $8000000080008000, $000000000000808B, $0000000080000001, + $8000000080008081, $8000000000008009, $000000000000008A, + $0000000000000088, $0000000080008009, $000000008000000A, + $000000008000808B, $800000000000008B, $8000000000008089, + $8000000000008003, $8000000000008002, $8000000000000080, + $000000000000800A, $800000008000000A, $8000000080008081, + $8000000000008080, $0000000080000001, $8000000080008008 + ); + + KECCAKF_ROT_CONSTS: array[0..23] of Integer = ( + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 + ); + + KECCAKF_PILN: array[0..23] of Integer = ( + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 + ); + +function ROTL64(Q: TUInt64; N: Integer): TUInt64; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (Q shl N) xor (Q shr (64 - N)); +end; + +// һ SHA3 㣬 Block ݣ State +procedure SHA3_Transform(var Context: TCnSHA3Context); +type + PUInt64Array = ^TUInt64Array; + TUInt64Array = array[0..4095] of TUInt64; +var + I, J, R, L: Integer; + P: PUInt64Array; + T: TUInt64; + BC: array[0..4] of TUInt64; +begin + P := PUInt64Array(@(Context.Block[0])); + I := 0; + L := Integer(Context.BlockLen div 8); + while I < L do + begin + Context.State[I] := Context.State[I] xor P^[I]; + Inc(I); + end; + + for R := 0 to Context.Round - 1 do + begin + // Theta + for I := 0 to 4 do + begin + BC[I] := Context.State[I] xor Context.State[I + 5] xor Context.State[I + 10] + xor Context.State[I + 15] xor Context.State[I + 20]; + end; + for I := 0 to 4 do + begin + T := BC[(I + 4) mod 5] xor ROTL64(BC[(I + 1) mod 5], 1); + for J := 0 to 4 do + Context.State[5 * J + I] := Context.State[5 * J + I] xor T; + end; + + // Rho Pi + T := Context.State[1]; + for I := 0 to 23 do + begin + J := KECCAKF_PILN[I]; + BC[0] := Context.State[J]; + Context.State[J] := ROTL64(T, KECCAKF_ROT_CONSTS[I]); + T := BC[0]; + end; + + // Chi + for J := 0 to 4 do + begin + for I := 0 to 4 do + BC[I] := Context.State[5 * J + I]; + + for I := 0 to 4 do + Context.State[5 * J + I] := Context.State[5 * J + I] xor + ((not BC[(I + 1) mod 5]) and BC[(I + 2) mod 5]); + end; + + // Iota + Context.State[0] := Context.State[0] xor KECCAKF_ROUND_CONSTS[R]; + end; +end; + +procedure SHA3Init(var Context: TCnSHA3Context; SHA3Type: TSHA3Type; + DigestByteLength: Cardinal = 0); +begin + FillChar(Context.State, SizeOf(Context.State), 0); + FillChar(Context.Block, SizeOf(Context.Block), 0); + Context.Index := 0; + Context.Round := SHA3_ROUNDS; + + case SHA3Type of + stSHA3_224: + begin + Context.BlockLen := SHA3_224_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_224_OUTPUT_LENGTH_BYTE; + end; + stSHA3_256: + begin + Context.BlockLen := SHA3_256_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_256_OUTPUT_LENGTH_BYTE; + end; + stSHA3_384: + begin + Context.BlockLen := SHA3_384_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_384_OUTPUT_LENGTH_BYTE; + end; + stSHA3_512: + begin + Context.BlockLen := SHA3_512_BLOCK_SIZE_BYTE; + Context.DigestLen := SHA3_512_OUTPUT_LENGTH_BYTE; + end; + stSHAKE128: + begin + Context.BlockLen := SHAKE128_BLOCK_SIZE_BYTE; + Context.DigestLen := DigestByteLength; + end; + stSHAKE256: + begin + Context.BlockLen := SHAKE256_BLOCK_SIZE_BYTE; + Context.DigestLen := DigestByteLength; + end; + end; +end; + +procedure SHA3Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +var + R, Idx: Cardinal; +begin + Idx := Context.Index; // Index Block еijʼλָ + repeat + if ByteLength < Context.BlockLen - Idx then + R := ByteLength //  + else + R := Context.BlockLen - Idx; // ܻʣ + + FillChar(Context.Block[Idx], SizeOf(Context.Block) - Idx, 0); // ȷβΪ 0 + Move(Input^, Context.Block[Idx], R); // Block ǰ벿ֲ + + if (Idx + R) < Context.BlockLen then // ûֲ + begin // ֻ Index λָ + Idx := Idx + R; + Break; + end; + + SHA3_Transform(Context); + Dec(ByteLength, R); + Idx := 0; + Inc(Input, R); + until False; + Context.Index := Idx; +end; + +procedure SHA3UpdateW(var Context: TCnSHA3Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + Content: PAnsiChar; + Len: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(Content, CharLength * SizeOf(WideChar)); + try + Len := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(Content), CharLength * SizeOf(WideChar), nil, nil); + SHA3Update(Context, Content, Len); + finally + FreeMem(Content); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SHA3Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +// SHA3_224/256/384/512 ר +procedure SHA3Final(var Context: TCnSHA3Context; var Digest: TCnSHA3GeneralDigest); overload; +begin + Context.Block[Context.Index] := 6; + Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; + SHA3_Transform(Context); + Move(Context.State[0], Digest[0], Context.DigestLen); +end; + +// SHAKE128 SHAKE256 ר +procedure SHA3Final(var Context: TCnSHA3Context; out Digest: TBytes); overload; +var + Idx, DL: Cardinal; +begin + Context.Block[Context.Index] := $1F; + Context.Block[Context.BlockLen - 1] := Context.Block[Context.BlockLen - 1] or $80; + SHA3_Transform(Context); + + SetLength(Digest, Context.DigestLen); + if Context.DigestLen <= Context.BlockLen then + Move(Context.State[0], Digest[0], Context.DigestLen) + else + begin + DL := Context.DigestLen; + Idx := 0; + + while DL >= Context.BlockLen do + begin + Move(Context.State[0], Digest[Idx], Context.BlockLen); + Inc(Idx, Context.BlockLen); + Dec(DL, Context.BlockLen); + + if DL > 0 then + begin + FillChar(Context.Block[0], SizeOf(Context.Block), 0); + SHA3_Transform(Context); + end; + end; + + if DL > 0 then + Move(Context.State[0], Digest[Idx], DL); + end; +end; + +procedure SHA3_224Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_224); +end; + +procedure SHA3_224Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_224Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_224Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_256Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_256); +end; + +procedure SHA3_256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_256Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_256Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_384Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_384); +end; + +procedure SHA3_384Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_384Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_384Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +procedure SHA3_512Init(var Context: TCnSHA3Context); +begin + SHA3Init(Context, stSHA3_512); +end; + +procedure SHA3_512Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_512Final(var Context: TCnSHA3Context; var Digest: TCnSHA3_512Digest); +var + Res: TCnSHA3GeneralDigest; +begin + SHA3Final(Context, Res); + Move(Res[0], Digest[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +procedure SHAKE128Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); +begin + SHA3Init(Context, stSHAKE128, DigestByteLength); +end; + +procedure SHAKE128Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHAKE128Final(var Context: TCnSHA3Context; out Digest: TBytes); +begin + SHA3Final(Context, Digest); +end; + +procedure SHAKE256Init(var Context: TCnSHA3Context; DigestByteLength: Cardinal); +begin + SHA3Init(Context, stSHAKE256, DigestByteLength); +end; + +procedure SHAKE256Update(var Context: TCnSHA3Context; Input: PAnsiChar; ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHAKE256Final(var Context: TCnSHA3Context; out Digest: TBytes); +begin + SHA3Final(Context, Digest); +end; + +// ݿ SHA3_224λ +function SHA3_224(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_256λ +function SHA3_256(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_384λ +function SHA3_384(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_512λ +function SHA3_512(Input: PAnsiChar; ByteLength: Cardinal): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, Input, ByteLength); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_224 +function SHA3_224Buffer(const Buffer; Count: Cardinal): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_256 +function SHA3_256Buffer(const Buffer; Count: Cardinal): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_384 +function SHA3_384Buffer(const Buffer; Count: Cardinal): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHA3_512 +function SHA3_512Buffer(const Buffer; Count: Cardinal): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(Buffer), Count); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ݿ SHAKE128 +function SHAKE128Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(Buffer), Count); + SHAKE128Final(Context, Result); +end; + +// ݿ SHAKE256 +function SHAKE256Buffer(const Buffer; Count: Cardinal; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(Buffer), Count); + SHAKE256Final(Context, Result); +end; + +// ֽ SHA3_224 +function SHA3_224Bytes(Data: TBytes): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_256 +function SHA3_256Bytes(Data: TBytes): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_384 +function SHA3_384Bytes(Data: TBytes): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHA3_512 +function SHA3_512Bytes(Data: TBytes): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// ֽ SHAKE128 +function SHAKE128Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHAKE128Final(Context, Result); +end; + +// ֽ SHAKE256 +function SHAKE256Bytes(Data: TBytes; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SHAKE256Final(Context, Result); +end; + +// String ݽ SHA3_224 +function SHA3_224String(const Str: string): TCnSHA3_224Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_224StringA(AStr); +end; + +// String ݽ SHA3_256 +function SHA3_256String(const Str: string): TCnSHA3_256Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_256StringA(AStr); +end; + +// String ݽ SHA3_384 +function SHA3_384String(const Str: string): TCnSHA3_384Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_384StringA(AStr); +end; + +// String ݽ SHA3_512 +function SHA3_512String(const Str: string): TCnSHA3_512Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHA3_512StringA(AStr); +end; + +// String ݽ SHAKE128 +function SHAKE128String(const Str: string; DigestByteLength: Cardinal): TBytes; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHAKE128StringA(AStr, DigestByteLength); +end; + +// String ݽ SHAKE256 +function SHAKE256String(const Str: string; DigestByteLength: Cardinal): TBytes; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SHAKE256StringA(AStr, DigestByteLength); +end; + +// UnicodeString ݽֱӵ SHA3_224 㣬ת +{$IFDEF UNICODE} +function SHA3_224UnicodeString(const Str: string): TCnSHA3_224Digest; +{$ELSE} +function SHA3_224UnicodeString(const Str: WideString): TCnSHA3_224Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_256 㣬ת +{$IFDEF UNICODE} +function SHA3_256UnicodeString(const Str: string): TCnSHA3_256Digest; +{$ELSE} +function SHA3_256UnicodeString(const Str: WideString): TCnSHA3_256Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_384 㣬ת +{$IFDEF UNICODE} +function SHA3_384UnicodeString(const Str: string): TCnSHA3_384Digest; +{$ELSE} +function SHA3_384UnicodeString(const Str: WideString): TCnSHA3_384Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHA3_512 㣬ת +{$IFDEF UNICODE} +function SHA3_512UnicodeString(const Str: string): TCnSHA3_512Digest; +{$ELSE} +function SHA3_512UnicodeString(const Str: WideString): TCnSHA3_512Digest; +{$ENDIF} +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// UnicodeString ݽֱӵ SHAKE128 㣬ת +{$IFDEF UNICODE} +function SHAKE128UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; +{$ELSE} +function SHAKE128UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; +{$ENDIF} +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHAKE128Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SHAKE256 㣬ת +{$IFDEF UNICODE} +function SHAKE256UnicodeString(const Str: string; DigestByteLength: Cardinal): TBytes; +{$ELSE} +function SHAKE256UnicodeString(const Str: WideString; DigestByteLength: Cardinal): TBytes; +{$ENDIF} +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SHAKE256Final(Context, Result); +end; + +// AnsiString ݽSHA224 +function SHA3_224StringA(const Str: AnsiString): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_224 +function SHA3_224StringW(const Str: WideString): TCnSHA3_224Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_224); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_224_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_256 +function SHA3_256StringA(const Str: AnsiString): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_256 +function SHA3_256StringW(const Str: WideString): TCnSHA3_256Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_256); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_256_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_384 +function SHA3_384StringA(const Str: AnsiString): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_384 +function SHA3_384StringW(const Str: WideString): TCnSHA3_384Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_384); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_384_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHA3_512 +function SHA3_512StringA(const Str: AnsiString): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, PAnsiChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// WideString ݽ SHA3_512 +function SHA3_512StringW(const Str: WideString): TCnSHA3_512Digest; +var + Context: TCnSHA3Context; + Res: TCnSHA3GeneralDigest; +begin + SHA3Init(Context, stSHA3_512); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); + SHA3Final(Context, Res); + Move(Res[0], Result[0], SHA3_512_OUTPUT_LENGTH_BYTE); +end; + +// AnsiString ݽ SHAKE128 +function SHAKE128StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHAKE128Update(Context, PAnsiChar(Str), Length(Str)); + SHAKE128Final(Context, Result); +end; + +// WideString ݽ SHAKE128 +function SHAKE128StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE128Init(Context, DigestByteLength); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE128UpdateW = SHA3UpdateW + SHAKE128Final(Context, Result); +end; + +// AnsiString ݽ SHAKE256 +function SHAKE256StringA(const Str: AnsiString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHAKE256Update(Context, PAnsiChar(Str), Length(Str)); + SHAKE256Final(Context, Result); +end; + +// WideString ݽ SHAKE256 +function SHAKE256StringW(const Str: WideString; DigestByteLength: Cardinal): TBytes; +var + Context: TCnSHA3Context; +begin + SHAKE256Init(Context, DigestByteLength); + SHA3UpdateW(Context, PWideChar(Str), Length(Str)); // SHAKE256UpdateW = SHA3UpdateW + SHAKE256Final(Context, Result); +end; + +// SHA3Type ֻ stSHA3_224, stSHA3_256, stSHA3_384, stSHA3_512 +function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSHA3GeneralDigest; SHA3Type: TSHA3Type; CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + Context: TCnSHA3Context; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + SHA3Init(Context, SHA3Type); + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA3Update(Context, Buf, ReadBytes); + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// SHA3Type ֻ stSHAKE128 stSHAKE256 +function InternalSHA3Stream(Stream: TStream; const BufSize: Cardinal; + SHA3Type: TSHA3Type; DigestByteLength: Cardinal; out D: TBytes; + CallBack: TCnSHA3CalcProgressFunc): Boolean; overload; +var + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; + Context: TCnSHA3Context; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then + Exit; + if Size < BufSize then + BufLen := Size + else + BufLen := BufSize; + + CancelCalc := False; + SHA3Init(Context, SHA3Type, DigestByteLength); + + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SHA3Update(Context, Buf, ReadBytes); + + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then + Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SHA3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָ SHA3_224 +function SHA3_224Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_224Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ָ SHA3_256 +function SHA3_256Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_256Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ָ SHA3_384 +function SHA3_384Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_384Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ָ SHA3_512 +function SHA3_512Stream(Stream: TStream; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_512Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Dig, stSHA3_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ָӴճȿɱ SHAKE128 +function SHAKE128Stream(Stream: TStream; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE128, DigestByteLength, Result, CallBack); +end; + +// ָӴճȿɱ SHAKE256 +function SHAKE256Stream(Stream: TStream; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, stSHAKE256, DigestByteLength, Result, CallBack); +end; + +function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} +var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec: Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, + OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then + Exit; + try + if not GetFileInformationByHandle(H, Info) then + Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} +end; + +function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; + CallBack: TCnSHA3CalcProgressFunc): TCnSHA3GeneralDigest; overload; +var +{$IFDEF MSWINDOWS} + Context: TCnSHA3Context; + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, Result, SHA3Type, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA3Init(Context, SHA3Type); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA3Final(Context, Result); +{$ENDIF} + end; +end; + +function InternalSHA3File(const FileName: string; SHA3Type: TSHA3Type; + DigestByteLength: Cardinal; CallBack: TCnSHA3CalcProgressFunc): TBytes; overload; +var +{$IFDEF MSWINDOWS} + Context: TCnSHA3Context; + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSHA3Stream(Stream, STREAM_BUF_SIZE, SHA3Type, DigestByteLength, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SHA3Init(Context, SHA3Type, DigestByteLength); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SHA3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SHA3Final(Context, Result); +{$ENDIF} + end; +end; + +// ָļݽ SHA3_224 +function SHA3_224File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_224Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_224, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ָļݽ SHA3_256 +function SHA3_256File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_256Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_256, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ָļݽ SHA3_384 +function SHA3_384File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_384Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_384, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ָļݽ SHA3_512 +function SHA3_512File(const FileName: string; CallBack: TCnSHA3CalcProgressFunc): + TCnSHA3_512Digest; +var + Dig: TCnSHA3GeneralDigest; +begin + Dig := InternalSHA3File(FileName, stSHA3_512, CallBack); + Move(Dig[0], Result[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ָļݽӴճȿɱ SHAKE128 +function SHAKE128File(const FileName: string; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + Result := InternalSHA3File(FileName, stSHAKE128, DigestByteLength, CallBack); +end; + +// ָļݽӴճȿɱ SHAKE256 +function SHAKE256File(const FileName: string; DigestByteLength: Cardinal; + CallBack: TCnSHA3CalcProgressFunc): TBytes; +begin + Result := InternalSHA3File(FileName, stSHAKE256, DigestByteLength, CallBack); +end; + +// ʮƸʽ SHA3_224 Ӵֵ +function SHA3_224Print(const Digest: TCnSHA3_224Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_224Digest)); +end; + +// ʮƸʽ SHA3_256 Ӵֵ +function SHA3_256Print(const Digest: TCnSHA3_256Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_256Digest)); +end; + +// ʮƸʽ SHA3_384 Ӵֵ +function SHA3_384Print(const Digest: TCnSHA3_384Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_384Digest)); +end; + +// ʮƸʽ SHA3_512 Ӵֵ +function SHA3_512Print(const Digest: TCnSHA3_512Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSHA3_512Digest)); +end; + +// ʮƸʽ SHAKE128 Ӵֵ +function SHAKE128Print(const Digest: TBytes): string; +begin + Result := BytesToHex(Digest); +end; + +// ʮƸʽ SHAKE256 Ӵֵ +function SHAKE256Print(const Digest: TBytes): string; +begin + Result := BytesToHex(Digest); +end; + +// Ƚ SHA3_224 ӴֵǷ +function SHA3_224Match(const D1, D2: TCnSHA3_224Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_224Digest)); +end; + +// Ƚ SHA3_256 ӴֵǷ +function SHA3_256Match(const D1, D2: TCnSHA3_256Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_256Digest)); +end; + +// Ƚ SHA3_384 ӴֵǷ +function SHA3_384Match(const D1, D2: TCnSHA3_384Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_384Digest)); +end; + +// Ƚ SHA3_512 ӴֵǷ +function SHA3_512Match(const D1, D2: TCnSHA3_512Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSHA3_512Digest));; +end; + +// Ƚ SHAKE128 ӴֵǷ +function SHAKE128Match(const D1, D2: TBytes): Boolean; +begin + Result := CompareBytes(D1, D2); +end; + +// Ƚ SHAKE256 ӴֵǷ +function SHAKE256Match(const D1, D2: TBytes): Boolean; +begin + Result := CompareBytes(D1, D2); +end; + +// SHA3_224 Ӵֵת string +function SHA3_224DigestToStr(const Digest: TCnSHA3_224Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_224Digest)); +end; + +// SHA3_256 Ӵֵת string +function SHA3_256DigestToStr(const Digest: TCnSHA3_256Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_256Digest));; +end; + +// SHA3_384 Ӵֵת string +function SHA3_384DigestToStr(const Digest: TCnSHA3_384Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_384Digest)); +end; + +// SHA3_512 Ӵֵת string +function SHA3_512DigestToStr(const Digest: TCnSHA3_512Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSHA3_512Digest)); +end; + +// SHAKE128 Ӵֵת string +function SHAKE128DigestToStr(const Digest: TBytes): string; +begin + Result := BytesToString(Digest); +end; + +// SHAKE256 Ӵֵת string +function SHAKE256DigestToStr(const Digest: TBytes): string; +begin + Result := BytesToString(Digest); +end; + +procedure SHA3_224HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_224Digest; +begin + if KeyLength > HMAC_SHA3_224_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_224Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_224_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_256HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_256Digest; +begin + if KeyLength > HMAC_SHA3_256_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_256Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_256_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_384HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_384Digest; +begin + if KeyLength > HMAC_SHA3_384_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_384Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_384_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_512HmacInit(var Context: TCnSHA3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSHA3_512Digest; +begin + if KeyLength > HMAC_SHA3_512_BLOCK_SIZE_BYTE then + begin + Sum := SHA3_512Buffer(Key, KeyLength); + KeyLength := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Context.Ipad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $36); + FillChar(Context.Opad, HMAC_SHA3_512_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Context.Ipad[I] := Byte(Context.Ipad[I] xor Byte(Key[I])); + Context.Opad[I] := Byte(Context.Opad[I] xor Byte(Key[I])); + end; + + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, @(Context.Ipad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); +end; + +procedure SHA3_224HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_256HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_384HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_512HmacUpdate(var Context: TCnSHA3Context; Input: PAnsiChar; + ByteLength: Cardinal); +begin + SHA3Update(Context, Input, ByteLength); +end; + +procedure SHA3_224HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_224_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_224); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_224_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_256HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_256_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_256); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_256_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_384HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_384_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_384); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_384_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_512HmacFinal(var Context: TCnSHA3Context; var Output: TCnSHA3GeneralDigest); +var + Len: Integer; + TmpBuf: TCnSHA3GeneralDigest; +begin + Len := HMAC_SHA3_512_OUTPUT_LENGTH_BYTE; + SHA3Final(Context, TmpBuf); + SHA3Init(Context, stSHA3_512); + SHA3Update(Context, @(Context.Opad[0]), HMAC_SHA3_512_BLOCK_SIZE_BYTE); + SHA3Update(Context, @(TmpBuf[0]), Len); + SHA3Final(Context, Output); +end; + +procedure SHA3_224Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_224Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_224HmacInit(Context, Key, KeyByteLength); + SHA3_224HmacUpdate(Context, Input, ByteLength); + SHA3_224HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_256Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_256Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_256HmacInit(Context, Key, KeyByteLength); + SHA3_256HmacUpdate(Context, Input, ByteLength); + SHA3_256HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_384Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_384Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_384HmacInit(Context, Key, KeyByteLength); + SHA3_384HmacUpdate(Context, Input, ByteLength); + SHA3_384HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +procedure SHA3_512Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSHA3_512Digest); +var + Context: TCnSHA3Context; + Dig: TCnSHA3GeneralDigest; +begin + SHA3_512HmacInit(Context, Key, KeyByteLength); + SHA3_512HmacUpdate(Context, Input, ByteLength); + SHA3_512HmacFinal(Context, Dig); + Move(Dig[0], Output[0], Context.DigestLen); +end; + +end. diff --git a/CnPack/Crypto/CnSM3.dcu b/CnPack/Crypto/CnSM3.dcu new file mode 100644 index 0000000000000000000000000000000000000000..5702308fecc90851e7e1705244d10cf62f426a3c GIT binary patch literal 14942 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 hoP3Lj*(N*248(j>HZvNH_!X!X +================================================================================ +* ƣ +* Ԫƣ SM3 Ӵ㷨ʵֵԪ +* ԪߣCnPack 飨master@cnpack.org) +* οֲ goldboar C +* עԪʵ˹ SM3 Ӵ㷨Ӧ HMAC 㷨 +* ο㷨ĵSM3 Cryptographic Hash Algorith +* http://www.oscca.gov.cn/UpFile/20101222141857786.pdf +* +* ƽ̨Windows 7 + Delphi 5.0 +* ݲԣPWin9X/2000/XP/7 + Delphi 5/6 +* õԪеַϱػʽ +* ޸ļ¼2019.12.12 V1.2 +* ֧ TBytes +* 2019.04.15 V1.1 +* ֧ Win32/Win64/MacOS +* 2014.09.23 V1.0 +* ֲԪ +================================================================================ +|} + +interface + +{$I CnPack.inc} + +uses + Classes, SysUtils, CnNative, CnConsts {$IFDEF MSWINDOWS}, Windows {$ENDIF}; + +type + PCnSM3Digest = ^TCnSM3Digest; + TCnSM3Digest = array[0..31] of Byte; + {* SM3 Ӵս32 ֽ} + + TCnSM3Context = packed record + {* SM3 Ľṹ} + Total: array[0..1] of Cardinal; {!< number of bytes processed } + State: array[0..7] of Cardinal; {!< intermediate digest state } + Buffer: array[0..63] of Byte; {!< data block being processed } + Ipad: array[0..63] of Byte; {!< HMAC: inner padding } + Opad: array[0..63] of Byte; {!< HMAC: outer padding } + end; + PCnSM3Context = ^TCnSM3Context; + + TCnSM3CalcProgressFunc = procedure (ATotal, AProgress: Int64; + var Cancel: Boolean) of object; + {* SM3 ӴսȻص¼} + +function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; +{* ݿ SM3 㡣 + + + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵTCnSM3Digest - ص SM3 Ӵֵ + + } + +function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; +{* ݿ SM3 㡣 + + + const Buffer - ݿַ + Count: Cardinal - ݿֽڳ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3Bytes(Data: TBytes): TCnSM3Digest; +{* ֽ SM3 㡣 + + + Data: TBytes - ֽ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3String(const Str: string): TCnSM3Digest; +{* String ݽ SM3 㣬ע D2009 ϰ汾 string Ϊ UnicodeString + лὫǿת AnsiString м㡣 + + + const Str: string - ַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3StringA(const Str: AnsiString): TCnSM3Digest; +{* AnsiString ݽ SM3 㡣 + + + const Str: AnsiString - ַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3StringW(const Str: WideString): TCnSM3Digest; +{* WideString ַת SM3 㡣 + ǰ Windows » WideCharToMultyByte תΪ AnsiString ͣ + ƽֱ̨תΪ AnsiString ͣٽм㡣 + + + const Str: WideString - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$IFDEF UNICODE} + +function SM3UnicodeString(const Str: string): TCnSM3Digest; +{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת + + + const Str: string - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$ELSE} + +function SM3UnicodeString(const Str: WideString): TCnSM3Digest; +{* UnicodeString ݽֱӵ SM3 㣬ֱӼڲ UTF16 ݣת + + + const Str: WideString - Ŀַ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +{$ENDIF} + +function SM3File(const FileName: string; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +{* ָļݽ SM3 㡣 + + + const FileName: string - ļ + CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +function SM3Stream(Stream: TStream; CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +{* ָݽ SM3 㡣 + + + Stream: TStream - + CallBack: TCnSM3CalcProgressFunc - ȻصĬΪ + + ֵTCnSM3Digest - ص SM3 Ӵֵ +} + +// ⲿݽɢ SM3 㣬SM3Update ɶα + +procedure SM3Init(var Context: TCnSM3Context); +{* ʼһ SM3 ģ׼ SM3 + + + var Context: TCnSM3Context - ʼ SM3 + + ֵޣ +} + +procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); +{* ԳʼĶһݽ SM3 㡣 + ɶε㲻ͬݿ飬轫ͬݿƴڴС + + + var Context: TCnSM3Context - SM3 + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + + ֵޣ +} + +procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); +{* ּ㣬 SM3 Digest + + + var Context: TCnSM3Context - SM3 + var Digest: TCnSM3Digest - ص SM3 Ӵֵ + + ֵޣ +} + +function SM3Print(const Digest: TCnSM3Digest): string; +{* ʮƸʽ SM3 Ӵֵ + + + const Digest: TCnSM3Digest - ָ SM3 Ӵֵ + + ֵstring - ʮַ +} + +function SM3Match(const D1: TCnSM3Digest; const D2: TCnSM3Digest): Boolean; +{* Ƚ SM3 ӴֵǷȡ + + + const D1: TCnSM3Digest - Ƚϵ SM3 Ӵֵһ + const D2: TCnSM3Digest - Ƚϵ SM3 Ӵֵ + + ֵBoolean - Ƿ +} + +function SM3DigestToStr(const Digest: TCnSM3Digest): string; +{* SM3 Ӵֱֵת stringÿֽڶӦһַ + + + const Digest: TCnSM3Digest - ת SM3 Ӵֵ + + ֵstring - صַ +} + +procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSM3Digest); +{* SM3 HMACHash-based Message Authentication Code㣬 + ͨݵļϼԿĸҲмΡ + + + Key: PAnsiChar - SM3 Կݿַ + KeyByteLength: Integer - SM3 Կݿֽڳ + Input: PAnsiChar - ݿַ + ByteLength: Cardinal - ݿֽڳ + var Output: TCnSM3Digest - ص SM3 Ӵֵ + + ֵޣ +} + +implementation + +const + SM3Padding: array[0..63] of Byte = + ( + $80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ); + + SM3_T: array[0..63] of Cardinal = ( + $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, + $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, $79CC4519, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, + $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A, $7A879D8A + ); + + MAX_FILE_SIZE = 512 * 1024 * 1024; + // If file size <= this size (bytes), using Mapping, else stream + + HMAC_SM3_BLOCK_SIZE_BYTE = 64; + HMAC_SM3_OUTPUT_LENGTH_BYTE = 32; + +type + TSM3ProcessData = array[0..63] of Byte; + +procedure GetULongBe(var N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +var + D: Cardinal; +begin + D := (Cardinal(B[I]) shl 24) or (Cardinal(B[I + 1]) shl 16) or + (Cardinal(B[I + 2]) shl 8) or (Cardinal(B[I + 3])); + N := D; +end; + +procedure PutULongBe(N: Cardinal; B: PAnsiChar; I: Integer); {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + B[I] := AnsiChar(N shr 24); + B[I + 1] := AnsiChar(N shr 16); + B[I + 2] := AnsiChar(N shr 8); + B[I + 3] := AnsiChar(N); +end; + +function FF0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor Y xor Z; +end; + +function FF1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) or (Y and Z) or (X and Z); +end; + +function GG0(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor Y xor Z; +end; + +function GG1(X, Y, Z: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and Y) or ((not X) and Z); +end; + +function SM3Shl(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := (X and $FFFFFFFF) shl N; +end; + +// ѭơע N Ϊ 0 32 ʱֵΪ XN Ϊ 33 ʱֵ N Ϊ 1 ʱķֵ +function ROTL(X: Cardinal; N: Integer): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := SM3Shl(X, N) or (X shr (32 - N)); +end; + +function P0(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor ROTL(X, 9) xor ROTL(X, 17); +end; + +function P1(X: Cardinal): Cardinal; {$IFDEF SUPPORT_INLINE} inline; {$ENDIF} +begin + Result := X xor ROTL(X, 15) xor ROTL(X, 23); +end; + +procedure SM3Init(var Context: TCnSM3Context); +begin + Context.Total[0] := 0; + Context.Total[1] := 0; + + Context.State[0] := $7380166F; + Context.State[1] := $4914B2B9; + Context.State[2] := $172442D7; + Context.State[3] := $DA8A0600; + Context.State[4] := $A96F30BC; + Context.State[5] := $163138AA; + Context.State[6] := $E38DEE4D; + Context.State[7] := $B0FB0E4E; + + FillChar(Context.Buffer, SizeOf(Context.Buffer), 0); +end; + +// һδ 64 ֽҲ 512 λݿ +procedure SM3Process(var Context: TCnSM3Context; Data: PAnsiChar); +var + SS1, SS2, TT1, TT2: Cardinal; + W: array[0..67] of Cardinal; + W1: array[0..63] of Cardinal; + A, B, C, D, E, F, G, H: Cardinal; + Temp1, Temp2: Cardinal; + J: Integer; +begin + GetULongBe(W[ 0], Data, 0); + GetULongBe(W[ 1], Data, 4); + GetULongBe(W[ 2], Data, 8); + GetULongBe(W[ 3], Data, 12); + GetULongBe(W[ 4], Data, 16); + GetULongBe(W[ 5], Data, 20); + GetULongBe(W[ 6], Data, 24); + GetULongBe(W[ 7], Data, 28); + GetULongBe(W[ 8], Data, 32); + GetULongBe(W[ 9], Data, 36); + GetULongBe(W[10], Data, 40); + GetULongBe(W[11], Data, 44); + GetULongBe(W[12], Data, 48); + GetULongBe(W[13], Data, 52); + GetULongBe(W[14], Data, 56); + GetULongBe(W[15], Data, 60); + + for J := 16 to 67 do + begin + Temp1 := W[J - 16] xor W[J - 9]; + Temp2 := ROTL(W[J - 3], 15); + W[J] := P1(Temp1 xor Temp2) xor (ROTL(W[J - 13], 7) xor W[J - 6]); + end; + + for J := 0 to 63 do + W1[J] := W[J] xor W[J + 4]; + + // ѾW/W1ֵ + + A := Context.State[0]; + B := Context.State[1]; + C := Context.State[2]; + D := Context.State[3]; + E := Context.State[4]; + F := Context.State[5]; + G := Context.State[6]; + H := Context.State[7]; + + for J := 0 to 15 do + begin + SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); + SS2 := SS1 xor ROTL(A, 12); + TT1 := FF0(A, B, C) + D + SS2 + W1[J]; + TT2 := GG0(E, F, G) + H + SS1 + W[J]; + D := C; + C := ROTL(B, 9); + B := A; + A := TT1; + H := G; + G := ROTL(F, 19); + F := E; + E := P0(TT2); + end; + + for J := 16 to 63 do + begin + SS1 := ROTL((ROTL(A, 12) + E + ROTL(SM3_T[J], J)), 7); + SS2 := SS1 xor ROTL(A, 12); + TT1 := FF1(A, B, C) + D + SS2 + W1[J]; + TT2 := GG1(E, F, G) + H + SS1 + W[J]; + D := C; + C := ROTL(B,9); + B := A; + A := TT1; + H := G; + G := ROTL(F,19); + F := E; + E := P0(TT2); + end; + + Context.State[0] := Context.State[0] xor A; + Context.State[1] := Context.State[1] xor B; + Context.State[2] := Context.State[2] xor C; + Context.State[3] := Context.State[3] xor D; + Context.State[4] := Context.State[4] xor E; + Context.State[5] := Context.State[5] xor F; + Context.State[6] := Context.State[6] xor G; + Context.State[7] := Context.State[7] xor H; + + // +end; + +procedure SM3UpdateW(var Context: TCnSM3Context; Input: PWideChar; CharLength: Cardinal); +var +{$IFDEF MSWINDOWS} + pContent: PAnsiChar; + iLen: Cardinal; +{$ELSE} + S: string; // UnicodeString + A: AnsiString; +{$ENDIF} +begin +{$IFDEF MSWINDOWS} + GetMem(pContent, CharLength * SizeOf(WideChar)); + try + iLen := WideCharToMultiByte(0, 0, Input, CharLength, // ҳĬ 0 + PAnsiChar(pContent), CharLength * SizeOf(WideChar), nil, nil); + SM3Update(Context, pContent, iLen); + finally + FreeMem(pContent); + end; +{$ELSE} // MacOS ֱӰ UnicodeString ת AnsiString 㣬ַ֧ Windows Unicode ƽ̨ + S := StrNew(Input); + A := AnsiString(S); + SM3Update(Context, @A[1], Length(A)); +{$ENDIF} +end; + +procedure SM3Update(var Context: TCnSM3Context; Input: PAnsiChar; ByteLength: Cardinal); +var + Fill, Left: Cardinal; +begin + if (Input = nil) or (ByteLength <= 0) then + Exit; + + Left := Context.Total[0] and $3F; + Fill := 64 - Left; + + Context.Total[0] := Context.Total[0] + ByteLength; + Context.Total[0] := Context.Total[0] and $FFFFFFFF; + + if Context.Total[0] < ByteLength then + Context.Total[1] := Context.Total[1] + 1; + + if (Left <> 0) and (ByteLength >= Fill) then + begin + Move(Input^, Context.Buffer[Left], Fill); + SM3Process(Context, @(Context.Buffer[0])); + Input := Input + Fill; + ByteLength := ByteLength - Fill; + Left := 0; + end; + + while ByteLength >= 64 do + begin + SM3Process(Context, Input); + Input := Input + 64; + ByteLength := ByteLength - 64; + end; + + if ByteLength > 0 then + Move(Input^, Context.Buffer[Left], ByteLength); +end; + +procedure SM3Final(var Context: TCnSM3Context; var Digest: TCnSM3Digest); +var + Last, Padn: Cardinal; + High, Low: Cardinal; + MsgLen: array[0..7] of Byte; +begin + High := (Context.Total[0] shr 29) or (Context.Total[1] shl 3); + Low := Context.Total[0] shl 3; + + PutULongBe(High, @(MsgLen[0]), 0); + PutULongBe(Low, @(MsgLen[0]), 4); + + Last := Context.Total[0] and $3F; + if Last < 56 then + Padn := 56 - Last + else + Padn := 120 - Last; + + SM3Update(Context, @(SM3Padding[0]), Padn); + SM3Update(Context, @(MsgLen[0]), 8); + + PutULongBe(Context.State[0], @Digest, 0); + PutULongBe(Context.State[1], @Digest, 4); + PutULongBe(Context.State[2], @Digest, 8); + PutULongBe(Context.State[3], @Digest, 12); + PutULongBe(Context.State[4], @Digest, 16); + PutULongBe(Context.State[5], @Digest, 20); + PutULongBe(Context.State[6], @Digest, 24); + PutULongBe(Context.State[7], @Digest, 28); +end; + +function SM3(Input: PAnsiChar; ByteLength: Cardinal): TCnSM3Digest; +var + Ctx: TCnSM3Context; +begin + SM3Init(Ctx); + SM3Update(Ctx, Input, ByteLength); + SM3Final(Ctx, Result); +end; + +procedure SM3HmacStarts(var Ctx: TCnSM3Context; Key: PAnsiChar; KeyLength: Integer); +var + I: Integer; + Sum: TCnSM3Digest; +begin + if KeyLength > HMAC_SM3_BLOCK_SIZE_BYTE then + begin + Sum := SM3(Key, KeyLength); + KeyLength := HMAC_SM3_OUTPUT_LENGTH_BYTE; + Key := @(Sum[0]); + end; + + FillChar(Ctx.Ipad, HMAC_SM3_BLOCK_SIZE_BYTE, $36); + FillChar(Ctx.Opad, HMAC_SM3_BLOCK_SIZE_BYTE, $5C); + + for I := 0 to KeyLength - 1 do + begin + Ctx.Ipad[I] := Byte(Ctx.Ipad[I] xor Byte(Key[I])); + Ctx.Opad[I] := Byte(Ctx.Opad[I] xor Byte(Key[I])); + end; + + SM3Init(Ctx); + SM3Update(Ctx, @(Ctx.Ipad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); +end; + +procedure SM3HmacUpdate(var Ctx: TCnSM3Context; Input: PAnsiChar; Length: Cardinal); +begin + SM3Update(Ctx, Input, Length); +end; + +procedure SM3HmacFinish(var Ctx: TCnSM3Context; var Output: TCnSM3Digest); +var + Len: Integer; + TmpBuf: TCnSM3Digest; +begin + Len := HMAC_SM3_OUTPUT_LENGTH_BYTE; + SM3Final(Ctx, TmpBuf); + SM3Init(Ctx); + SM3Update(Ctx, @(Ctx.Opad[0]), HMAC_SM3_BLOCK_SIZE_BYTE); + SM3Update(Ctx, @(TmpBuf[0]), Len); + SM3Final(Ctx, Output); +end; + +procedure SM3Hmac(Key: PAnsiChar; KeyByteLength: Integer; Input: PAnsiChar; + ByteLength: Cardinal; var Output: TCnSM3Digest); +var + Ctx: TCnSM3Context; +begin + SM3HmacStarts(Ctx, Key, KeyByteLength); + SM3HmacUpdate(Ctx, Input, ByteLength); + SM3HmacFinish(Ctx, Output); +end; + +function SM3Buffer(const Buffer; Count: Cardinal): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(Buffer), Count); + SM3Final(Context, Result); +end; + +function SM3Bytes(Data: TBytes): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(@Data[0]), Length(Data)); + SM3Final(Context, Result); +end; + +// String ݽ SM3 ת +function SM3String(const Str: string): TCnSM3Digest; +var + AStr: AnsiString; +begin + AStr := AnsiString(Str); + Result := SM3StringA(AStr); +end; + +// AnsiString ݽ SM3 ת +function SM3StringA(const Str: AnsiString): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(Str), Length(Str)); + SM3Final(Context, Result); +end; + +// WideString ݽ SM3 ת +function SM3StringW(const Str: WideString): TCnSM3Digest; +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3UpdateW(Context, PWideChar(Str), Length(Str)); + SM3Final(Context, Result); +end; + +// UnicodeString ݽֱӵ SM3 㣬ת +{$IFDEF UNICODE} +function SM3UnicodeString(const Str: string): TCnSM3Digest; +{$ELSE} +function SM3UnicodeString(const Str: WideString): TCnSM3Digest; +{$ENDIF} +var + Context: TCnSM3Context; +begin + SM3Init(Context); + SM3Update(Context, PAnsiChar(@Str[1]), Length(Str) * SizeOf(WideChar)); + SM3Final(Context, Result); +end; + +function InternalSM3Stream(Stream: TStream; const BufSize: Cardinal; var D: + TCnSM3Digest; CallBack: TCnSM3CalcProgressFunc = nil): Boolean; +var + Context: TCnSM3Context; + Buf: PAnsiChar; + BufLen: Cardinal; + Size: Int64; + ReadBytes: Cardinal; + TotalBytes: Int64; + SavePos: Int64; + CancelCalc: Boolean; +begin + Result := False; + Size := Stream.Size; + SavePos := Stream.Position; + TotalBytes := 0; + if Size = 0 then Exit; + if Size < BufSize then BufLen := Size + else BufLen := BufSize; + + CancelCalc := False; + SM3Init(Context); + GetMem(Buf, BufLen); + try + Stream.Position := 0; + repeat + ReadBytes := Stream.Read(Buf^, BufLen); + if ReadBytes <> 0 then + begin + Inc(TotalBytes, ReadBytes); + SM3Update(Context, Buf, ReadBytes); + if Assigned(CallBack) then + begin + CallBack(Size, TotalBytes, CancelCalc); + if CancelCalc then Exit; + end; + end; + until (ReadBytes = 0) or (TotalBytes = Size); + SM3Final(Context, D); + Result := True; + finally + FreeMem(Buf, BufLen); + Stream.Position := SavePos; + end; +end; + +// ָļݽSM3ת +function SM3File(const FileName: string; + CallBack: TCnSM3CalcProgressFunc): TCnSM3Digest; +var +{$IFDEF MSWINDOWS} + FileHandle: THandle; + MapHandle: THandle; + ViewPointer: Pointer; + Context: TCnSM3Context; +{$ENDIF} + Stream: TStream; + FileIsZeroSize: Boolean; + + function FileSizeIsLargeThanMaxOrCanNotMap(const AFileName: string; out IsEmpty: Boolean): Boolean; +{$IFDEF MSWINDOWS} + var + H: THandle; + Info: BY_HANDLE_FILE_INFORMATION; + Rec : Int64Rec; +{$ENDIF} + begin +{$IFDEF MSWINDOWS} + Result := False; + IsEmpty := False; + H := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); + if H = INVALID_HANDLE_VALUE then Exit; + try + if not GetFileInformationByHandle(H, Info) then Exit; + finally + CloseHandle(H); + end; + Rec.Lo := Info.nFileSizeLow; + Rec.Hi := Info.nFileSizeHigh; + Result := (Rec.Hi > 0) or (Rec.Lo > MAX_FILE_SIZE); + IsEmpty := (Rec.Hi = 0) and (Rec.Lo = 0); +{$ELSE} + Result := True; // Windows ƽ̨ Trueʾ Mapping +{$ENDIF} + end; + +begin + FileIsZeroSize := False; + if FileSizeIsLargeThanMaxOrCanNotMap(FileName, FileIsZeroSize) then + begin + // 2G ļ Map ʧܣ Windows ƽ̨ʽѭ + Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); + finally + Stream.Free; + end; + end + else + begin +{$IFDEF MSWINDOWS} + SM3Init(Context); + FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or + FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or + FILE_FLAG_SEQUENTIAL_SCAN, 0); + if FileHandle <> INVALID_HANDLE_VALUE then + begin + try + MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); + if MapHandle <> 0 then + begin + try + ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0); + if ViewPointer <> nil then + begin + try + SM3Update(Context, ViewPointer, GetFileSize(FileHandle, nil)); + finally + UnmapViewOfFile(ViewPointer); + end; + end + else + begin + raise Exception.Create(SCnErrorMapViewOfFile + IntToStr(GetLastError)); + end; + finally + CloseHandle(MapHandle); + end; + end + else + begin + if not FileIsZeroSize then + raise Exception.Create(SCnErrorCreateFileMapping + IntToStr(GetLastError)); + end; + finally + CloseHandle(FileHandle); + end; + end; + SM3Final(Context, Result); +{$ENDIF} + end; +end; + +// ָ SM3 +function SM3Stream(Stream: TStream; + CallBack: TCnSM3CalcProgressFunc = nil): TCnSM3Digest; +begin + InternalSM3Stream(Stream, 4096 * 1024, Result, CallBack); +end; + +function SM3Print(const Digest: TCnSM3Digest): string; +begin + Result := DataToHex(@Digest[0], SizeOf(TCnSM3Digest)); +end; + +function SM3Match(const D1, D2: TCnSM3Digest): Boolean; +begin + Result := CompareMem(@D1[0], @D2[0], SizeOf(TCnSM3Digest)); +end; + +function SM3DigestToStr(const Digest: TCnSM3Digest): string; +begin + Result := MemoryToString(@Digest[0], SizeOf(TCnSM3Digest)); +end; + +end. From 8266f5e634591f8246dc91119b73e3d2a6f092f3 Mon Sep 17 00:00:00 2001 From: freitasjca Date: Sat, 14 Mar 2026 11:06:01 +0000 Subject: [PATCH 5/5] Remove tracked .dcu files and add to .gitignore --- .gitignore | 63 +++++++++++++++++++++++++++++++++++ CnPack/Crypto/CnAES.dcu | Bin 122925 -> 0 bytes CnPack/Crypto/CnBase64.dcu | Bin 7426 -> 0 bytes CnPack/Crypto/CnConsts.dcu | Bin 14305 -> 0 bytes CnPack/Crypto/CnDES.dcu | Bin 30941 -> 0 bytes CnPack/Crypto/CnFloat.dcu | Bin 15913 -> 0 bytes CnPack/Crypto/CnKDF.dcu | Bin 13854 -> 0 bytes CnPack/Crypto/CnMD5.dcu | Bin 15598 -> 0 bytes CnPack/Crypto/CnNative.dcu | Bin 48972 -> 0 bytes CnPack/Crypto/CnPemUtils.dcu | Bin 16968 -> 0 bytes CnPack/Crypto/CnRandom.dcu | Bin 5673 -> 0 bytes CnPack/Crypto/CnSHA1.dcu | Bin 10859 -> 0 bytes CnPack/Crypto/CnSHA2.dcu | Bin 30907 -> 0 bytes CnPack/Crypto/CnSHA3.dcu | Bin 31943 -> 0 bytes CnPack/Crypto/CnSM3.dcu | Bin 14942 -> 0 bytes 15 files changed, 63 insertions(+) create mode 100644 .gitignore delete mode 100644 CnPack/Crypto/CnAES.dcu delete mode 100644 CnPack/Crypto/CnBase64.dcu delete mode 100644 CnPack/Crypto/CnConsts.dcu delete mode 100644 CnPack/Crypto/CnDES.dcu delete mode 100644 CnPack/Crypto/CnFloat.dcu delete mode 100644 CnPack/Crypto/CnKDF.dcu delete mode 100644 CnPack/Crypto/CnMD5.dcu delete mode 100644 CnPack/Crypto/CnNative.dcu delete mode 100644 CnPack/Crypto/CnPemUtils.dcu delete mode 100644 CnPack/Crypto/CnRandom.dcu delete mode 100644 CnPack/Crypto/CnSHA1.dcu delete mode 100644 CnPack/Crypto/CnSHA2.dcu delete mode 100644 CnPack/Crypto/CnSHA3.dcu delete mode 100644 CnPack/Crypto/CnSM3.dcu diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8454266 --- /dev/null +++ b/.gitignore @@ -0,0 +1,63 @@ +modules/ +dist/ +static/ +**/Win32/ +**/Win64/ +**/Linux64/ +**/__history/ +**/__recovery/ +src/*.~* +__history/ +__recovery/ +packages/Win32/ +packages/Win64/ +packages/Linux64/ +packages/dcu/ +packages/dcp/ +packages/bpl/ +*.res +*.exe +*.dll +*.bpl +*.bpi +*.dcp +*.bpl +*.so +*.apk +*.drc +*.map +*.dres +*.rsm +*.tds +*.dcu +*.lib +*.a +*.o +*.ocx +*.local +*.identcache +*.projdata +*.tvsconfig +*.dsk +*.dcu +*.exe +*.ico +*.so +*.~* +*.a +*.stat +*.skincfg + +# Mac +*.DS_Store + +#FPC/Laz +lib/ +backup/ +*.lps + +# Code coverage reports +**/console/ +**/vcl/ +dunitx-results.xml +*.bak diff --git a/CnPack/Crypto/CnAES.dcu b/CnPack/Crypto/CnAES.dcu deleted file mode 100644 index ebc666a410074a233b156bd06d693c171451fb02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122925 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 U5XKli4!pF diff --git a/CnPack/Crypto/CnConsts.dcu b/CnPack/Crypto/CnConsts.dcu deleted file mode 100644 index c867ed279f4c00fe26ff633e118584d938e5bedb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14305 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 e3USNw2)Y>N%(KXha^|S(k2<+r=u|5s diff --git a/CnPack/Crypto/CnDES.dcu b/CnPack/Crypto/CnDES.dcu deleted file mode 100644 index 86e855f0e249b9d709daafffd26601b8f2c8b4ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30941 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

NA(3P9!?JiueiT3|zuV96ev0!$^2X$c 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 IRjl;?0`Q@bKL7v# diff --git a/CnPack/Crypto/CnSM3.dcu b/CnPack/Crypto/CnSM3.dcu deleted file mode 100644 index 5702308fecc90851e7e1705244d10cf62f426a3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14942 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 hoP3Lj*(N*248(j>HZvNH_!X!X

GjU1lO-!A@MOz*mL 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 WtWPF_AP}eC1XBtgT&1reuKxu#%R$fp diff --git a/CnPack/Crypto/CnNative.dcu b/CnPack/Crypto/CnNative.dcu deleted file mode 100644 index 6b75b118ea19893f0e12fe282c3f47c9989c3dbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48972 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 diff --git a/CnPack/Crypto/CnPemUtils.dcu b/CnPack/Crypto/CnPemUtils.dcu deleted file mode 100644 index b14a181ea709064b3476fff66071bca6173099f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16968 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 HV0HfoxNO-h diff --git a/CnPack/Crypto/CnRandom.dcu b/CnPack/Crypto/CnRandom.dcu deleted file mode 100644 index c89e954877a4cd1e8e54c20ff7c9e1f2ca04318b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5673 zcmdTIYiv{3`OD3@&W&sG7HR{fHcPS$1q%|Oj4|rOz5z;JI1Z1NM=$pEBXzEgeNB>z zw4q@VA!XV_TGc7b=&DUyD@ALyb{(p;tfefYQb+q^qw3T}6GKn}b4Av8D#ZKFx%WCZ z1U9Yz=HPR_^Sxj9JJ+=4!^*EM1<2wD=!X;BidRwsv7Wi|?9CqlY>r#qN{8fs(iu_w zvjg4xxVX(=amJL^2Xn{`~BIf2hdUeyCgat4{H7 zN{S}KKlN9K$_?CBS=}Zj!|qr>j!?n_2BA|5%5Etd75n^hTt!_^E+97sRXO2~DM>Yv z@>6nj0l7&I#uBne&XId4xx`TJi6rBa>JKXvyEKQDgHkGr{wRT{oQP3c&d)ZvcRL!B z6!eA?Dh#3Kge)7B!$=A8+ZA=gy1yQIkRcHPgvbnrcBq?j@y!u4^-B6KBi?o?~ z80}{`OK0RMxjjf5AylZf0U{WQ_a#z_pHVCtC!BStFq(+X&U0BdnrB40Q&V z_^9-TbsDc4xw$%M^O-Px2cB~Ui+x4|X>6|u%G+oL*=QeWxQ@rYTl|5d-B`qU#EDxV z*2{8M(4m$0*XJ%21xZtTd&@uihu;Yn_%!sT*6x>syk~d2*F#$;WW$uSNJ&*pBw~s8 z?9cxYmFksnN2O#^rb_(*oDN#>v@8XB5aFS^bf{1Zs5KV2QMc(j254|nJhc|Gw#q%R zM1NxOz~AR47jfn8VRPV~pst+GCZ7_OY*yfQu`Nf{q{RqoSz zsDcq1{fASLgh6PeBL4NcF?Jl_;G5t6Bj;Z~KcmR{0zIff$_vq+5@$w6+_UsL83jgi{ev7MCwMVp0}ezpcy zl`f*4zyR01>#Kj5bJjNltb=Ny(X$IB8|tk9CDxW-5{^xD8>*Ke07r0*Lj)S29-MfN z;vYbDx!b$9!*_6(=-uAD*WKRc6ZiN~!3Kb0B&Vy3HF}%4dxyBUQ>3(wsK2^Q!+XRQ z(I=Wo_Ua`a-u7Jwy`7B*o4ZVKPtL?%P0tRp6NDT}* zEb(whB6h?APz4TKJoywYzZ6mA1fp!s`1<2AvXp_NAkfs7Nd3PZ`(Ay#_nrR_^s3{c;>aO{}YH8j^eG3BAe#VU!PTrrb zEj0??9EnDo`c*lJYW@3P*aB+{IbsDzKGlG+W*k<8CP7dtMWz{>eXDc)l`QTeiqpyP^Gsp%Ej+WSoE(3kw@-+LB3Tm@$i zg-avz3^JP{Z=flx#DNK?xe8+DCK-F42jeDGDq~*|cSF6&<<9HBtAY3jHkLku%Eo@9Aq<(s_qVqz=Q7lH~9$8Uo)6y3U#9Go0 zn~rtIQVQ)|%N0|U*30(1?G%Zv>!tezJJ+-p0bvq>dJ0USGY$^h@4ik|N~l`d06(P` zu4D`3njf>zn*Vcut+i8)#pfA4l+RylV{bl@r|>e5(e|S+C{V>YC~=Id&D|hKVxJn$ zAyCrXRuBN{)6D^43}EHZQdl!e=73Z`0)7uAt)t^}uoz#dpE=DC8`v~vFWATOJ%D$_ zI=G#8JHG`=@QvF=w7rSAm>r#gyKS%{6uth?9!8vBhz>rX@0c4{uESq;<6!Y^L+unS zM$fyGOBA(A@4sv{h0H5Gca2OBot+x)$_$IQ&WW?oFflBqyP-P|zi>)ScU+-dLz%o~ z6Rs2DwZVaFka{qTsPuniIl{z-#pz=M)AUA3J<=`QA@Hq=9Oxc1|fuR=ik>Lo#g`TZUsht!v&bvfOEX$88Cic3^})g>n$`2f*wff!X9VP7 zWjH>O`Z@#H^6~1UNciLrA6@z6Dnq!iH}6TA!HP6|IC7z3!i%+@Y4|XoRF(Ux$k16~ zSj-G}-NGgq!If5sedw?26)yb|$S}R$j%>=7O$qE^mfE{_|J#E0uq^WU8;o1`YxJHT z|9lZ;=32oqIZX%Be{)^)N(*3-Zx|8!Mn7|?>p>R-*=(DSE=;X-XBWw0T<@?tWKM~h zGjymh7OcZV3}DO0t360qSceQcgChgWOjR(GXu_0FBr@TK4`)-iuqTjTH@5Rl>I@_5 z8gw6K@OVm`S>T4l?8d%DZm<;2P<`mh3wq&o)zqX>Z6h=KxNFtB^qhDTh6ZkdDh&-} z;OWPQ24>)B7h>}e%6obT_R+SX3>@8plME-2OV@k_;n|){zIba`yfh+SG2p3@R&24U z5%CgZ%(hMs4NPZK?^1;)#hcU_t?3&kUZN>8=4_ZAn20fGzZe|&0#Yj|K_9gD;^}2_ zn7LyEx7eh08IyKi!Zd2r=foK{*KyST1-0LG)M8j>K3Cpd`1H*FKh8Q@gKyH5gIduI zrU|8&g;gobQ-&1J(yP^NHO1s54OGt(ye3A0jM~Xq2^nSob_qlfh*cmyf!G96B#;t; zlnJClAWH>uzd$+!(k2k^Mi>J!<|Ly6X>r0hA;$$cL&&oNOb{|Cz@z}@J^XkxKVHkn zH}T_Te7uUBFCwE>exH?J<21p`$$2L~fox`mN^*WFf2M@5e}KTnRbpVxLm|fRq}mxFm2+QHh3s-lyBMxGt2quTF97qGDz~kTm_%0fkLi= zFXbwsl&hLIRLUX8CcbGM{stLDvX?))21KrmOjeRfD?h%4t>}I|16ZIUXNuHxxXr;% z&PpaLXh3I*aD^^BpDyBeayFn)2`_TCJnlR2T?@AdxF2og9{YfY?*qJQ<(>3@D9Gz2 z7H33+@l9z3b%xVgUh%d_rWx7CqLj|2KO-!WN`b*X_&)pd=usk q_t%`5H{9R2fQiEWEYD$@5IA3I!Ke|q;lXHe&r|`&aWGc{(!T-6_uBvf diff --git a/CnPack/Crypto/CnSHA1.dcu b/CnPack/Crypto/CnSHA1.dcu deleted file mode 100644 index a3f75043eb9f12c9d50a84dbf880dc9592c6e5f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10859 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 QlTU=35CcrI#ct;Ke<$eb%>V!Z diff --git a/CnPack/Crypto/CnSHA2.dcu b/CnPack/Crypto/CnSHA2.dcu deleted file mode 100644 index b080c2a50656f8ebf30bc3076405071038294457..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30907 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