{***************************************************************************** The DEC team (see file NOTICE.txt) licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. A copy of this licence is found in the root directory of this project in the file LICENCE.txt or alternatively at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *****************************************************************************} /// /// Hash functions. Be aware that the x86 ASM implementations, if activated /// by the define, are provided by DECHash.asm86.inc! /// unit DECHash; interface {$INCLUDE DECOptions.inc} uses {$IFDEF FPC} SysUtils, Classes, {$ELSE} System.SysUtils, System.Classes, {$ENDIF} DECBaseClass, DECFormatBase, DECUtil, DECHashBase, DECHashAUthentication, DECHashBitBase, DECTypes; type // Hash Classes THash_MD2 = class; THash_MD4 = class; THash_MD5 = class; THash_RipeMD128 = class; THash_RipeMD160 = class; THash_RipeMD256 = class; THash_RipeMD320 = class; THash_SHA0 = class; // SHA-0 THash_SHA1 = class; // SHA-1 THash_SHA224 = class; // SHA-2, SHA-224 THash_SHA256 = class; // SHA-2, SHA-256 THash_SHA384 = class; // SHA-2, SHA-384 THash_SHA512 = class; // SHA-2, SHA-512 THash_SHA3_224 = class; THash_SHA3_256 = class; THash_SHA3_384 = class; THash_SHA3_512 = class; THash_Haval128 = class; THash_Haval160 = class; // Haval 160, 3 Rounds THash_Haval192 = class; // Haval 192, 4 Rounds THash_Haval224 = class; // Haval 224, 4 Rounds THash_Haval256 = class; // Haval 256, 5 Rounds THash_Tiger = class; THash_Panama = class; {$IFDEF OLD_WHIRLPOOL_NAMES} THash_Whirlpool = class; THash_Whirlpool1New = class; {$ENDIF} THash_Whirlpool0 = class; THash_Whirlpool1 = class; // differs, depending on OLD_WHIRLPOOL_NAMES define THash_WhirlpoolT = class; THash_Square = class; THash_Snefru128 = class; // derived from the Xerox Secure Hash Function THash_Snefru256 = class; // " - " THash_Sapphire = class; /// /// Implementation of the MD2 hash algorithm. Considered to be broken, /// at least on paper. /// THash_MD2 = class(TDECHashAuthentication) private FDigest: array[0..63] of Byte; protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; procedure DoDone; override; public function Digest: PByteArray; override; class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; end; /// /// Base class for the MD4 hash alrogithm and for other hash-algorithms which /// are close relatives to the MD4 algorithm like the RipeMD ones. /// THashBaseMD4 = class(TDECHashAuthentication) private FDigest: array[0..9] of UInt32; protected procedure DoInit; override; procedure DoDone; override; public function Digest: PByteArray; override; class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; end; /// /// The MD4 algorithm is considered to be broken, at least on paper. /// THash_MD4 = class(THashBaseMD4) protected procedure DoTransform(Buffer: PUInt32Array); override; end; /// /// The MD5 algorithm is considered to be broken. Using it in HMAC algorithms /// is still ok. /// THash_MD5 = class(THashBaseMD4) protected procedure DoTransform(Buffer: PUInt32Array); override; end; /// /// Do not confuse with the original RipeMD algorithm which ís being /// considered to be unsafe anyway. Considered to be broken due to the only /// 128 Bit long message digest result. /// THash_RipeMD128 = class(THashBaseMD4) protected procedure DoTransform(Buffer: PUInt32Array); override; end; THash_RipeMD160 = class(THashBaseMD4) protected procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; end; THash_RipeMD256 = class(THashBaseMD4) protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; end; THash_RipeMD320 = class(THashBaseMD4) protected procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; end; /// /// Implementation of the SHA0 hash algorithm. This is the original version /// of the SHA algorithm released in 1993. In 1995 some security issues have /// been identified in this algorithm so he got replaced by the slightly /// modified SHA1 algorithm. The recommendation is to not use this SHA0 /// algorithm at all. It is only being provided for scenarios where /// compatibility with this algorithm is required. /// THash_SHA0 = class(THashBaseMD4) protected procedure DoTransform(Buffer: PUInt32Array); override; procedure DoDone; override; public class function DigestSize: UInt32; override; end; {$IFDEF OLD_SHA_NAME} /// /// Implementation of the SHA0 hash algorithm. This is the original version /// of the SHA algorithm released in 1993. In 1995 some security issues have /// been identified in this algorithm so he got replaced by the slightly /// modified SHA1 algorithm. The recommendation is to not use this SHA0 /// algorithm at all. It is only being provided for scenarios where /// compatibility with this algorithm is required. /// THash_SHA = class(THash_SHA0) {$IFDEF X86ASM} protected procedure DoTransform(Buffer: PUInt32Array); override; end {$ENDIF}; {$ENDIF} /// /// Implementation of the SHA1 hash algorithm. At least since February 2017 /// collisions have been found for this algorithm so it's now completely /// clear that it should not be used if possible! Use SHA256 or SHA512 /// instead! /// THash_SHA1 = class(THash_SHA0); /// /// This algorithm is part of the SHA2 series of hash algorithms. /// THash_SHA256 = class(THash_SHA0) protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; end; /// /// This algorithm is part of the SHA2 series of hash algorithms. /// German BSI recommends not to use this algorithm, they recommend SHA256 /// or higher instead. /// THash_SHA224 = class(THash_SHA256) protected procedure DoInit; override; public class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; end; /// /// This algorithm is part of the SHA2 series of hash algorithms. /// THash_SHA384 = class(TDECHashAuthentication) private FDigest: array[0..7] of Int64; protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; procedure DoDone; override; public function Digest: PByteArray; override; class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; end; /// /// This algorithm is part of the SHA2 series of hash algorithms. /// THash_SHA512 = class(THash_SHA384) protected procedure DoInit; override; public class function DigestSize: UInt32; override; end; /// /// Base class for tall SHA3 implementations /// THash_SHA3Base = class(TDECHashBit) strict private // Declarations for SHA3. Must be declared here to allow private methods // to use these types as well. const KeccakPermutationSize = 1600; /// /// Maximum bitrate? If yes this would be higher than any value listed here: /// https://keccak.team/keccak.html /// KeccakMaximumRate = 1536; /// /// KeccakPermutationSize converted into bytes instead of bits /// KeccakPermutationSizeInBytes = KeccakPermutationSize div 8; /// /// KeccakMaximumRate converted into bytes instead of bits /// KeccakMaximumRateInBytes = KeccakMaximumRate div 8; /// /// Number of times to run the algorithm on the data /// cKeccakNumberOfRounds = 24; /// /// Precalculated values for the 24 rounds of the algorithm /// cRoundConstants : array[0..23] of UInt64 = ( UInt64($0000000000000001), UInt64($0000000000008082), UInt64($800000000000808A), UInt64($8000000080008000), UInt64($000000000000808B), UInt64($0000000080000001), UInt64($8000000080008081), UInt64($8000000000008009), UInt64($000000000000008A), UInt64($0000000000000088), UInt64($0000000080008009), UInt64($000000008000000A), UInt64($000000008000808B), UInt64($800000000000008B), UInt64($8000000000008089), UInt64($8000000000008003), UInt64($8000000000008002), UInt64($8000000000000080), UInt64($000000000000800A), UInt64($800000008000000A), UInt64($8000000080008081), UInt64($8000000000008080), UInt64($0000000080000001), UInt64($8000000080008008) ); type TState_B = packed array[0..KeccakPermutationSizeInBytes-1] of UInt8; TState_L = packed array[0..(KeccakPermutationSizeInBytes) div 4 - 1] of Int32; TKDQueue = packed array[0..KeccakMaximumRateInBytes-1] of UInt8; /// /// Calculation status of the algorithm /// TSpongeState = packed record State : TState_B; /// /// Data of the queue to be processed /// DataQueue : TKDQueue; /// /// Bitrate r of Keccak /// Rate : UInt16; /// /// Capacity c of Keccak /// Capacity : UInt16; /// /// How many bits are in the queue /// BitsInQueue : UInt16; /// /// Length of the hash value to generate in bit /// FixedOutputLength : UInt16; /// /// Number of bits which can be squeezed /// bitsAvailableForSqueezing : UInt16; /// /// Flag which is set to true when entering the /// squeezing state. Suppresses further absorb calls. /// SqueezeActive : Boolean; /// /// If an operation fails it sets this error code /// // Fill3: packed array[405..HASHCTXSIZE] of byte; end; /// /// Buffer type /// TBABytes = array[0..65535] of UInt8; /// /// Pointer to a buffer /// PBABytes = ^TBABytes; /// /// Type for the generated hash value /// TSHA3Digest = array[0..63] of UInt8; var /// /// The generated hash value is stored here /// FDigest : TSHA3Digest; /// /// Function to give input data for the sponge function to absorb /// /// /// Pointer to the data to work on /// /// /// Length of the data passed via the pointer in bit /// /// /// Raises an EDECHashEception when DataBit len not divideable by 8 without /// reminder or when already in squeezin state. /// procedure Absorb(Data: PBABytes; DatabitLen: Int32); /// /// Absorb remaining bits from queue /// procedure AbsorbQueue; {$IFDEF PUREPASCAL} /// /// Circular left shift /// /// /// Value to be shifted /// /// /// Number of bits the value will be shifted /// /// /// Shifted value /// function RotL(const x: UInt64; c: Integer): UInt64; inline; /// /// Circular left shift by 1 /// /// /// Value to be shifted /// /// /// Shifted value /// function RotL1(var x: UInt64): UInt64; inline; {$ENDIF} /// /// Permutates the values in the passed state /// /// /// State to permutate /// procedure KeccakPermutation(var State: TState_L); /// /// Carries out the XorIntoState and the permutation /// /// /// State of the algorithm which gets modified by the permutation in this method /// /// /// Pointer to the data to operate on /// /// /// Number of times the loop in this algorithm has tpo be carried out /// procedure KeccakAbsorb(var state: TState_B; data: PUInt64; laneCount: Integer); /// /// Include input message data bits into the sponge state /// procedure XORIntoState(var state: TState_L; pI: PUInt64; laneCount: Integer); /// /// Update state with DataBitLen bits from data. May be called multiple /// times, only the last DataBitLen may be a non-multiple of 8 /// (the corresponding byte) must be MSB aligned, i.e. in the /// (databitlen and 7) most significant bits. /// /// /// Data to work on /// /// /// Length of the data in bits /// procedure DoUpdate(Data: Pointer; DataBitLen: Int32); /// /// Squeeze output data from the sponge function. If the sponge function /// was in the absorbing phase, this function switches it to the squeezing /// phase. /// /// /// pointer to the buffer where to store the output data /// /// /// number of output bits desired, must be a multiple of 8. /// /// /// 0 if successful, 1 otherwise. /// procedure Squeeze(var Output: TSHA3Digest; OutputLength: Int32); /// /// The algorithm starts in the absorb phase (one puts data into the sponge) /// and ends with the squeze phase (one squeezes the sponge) and this method /// does everything needed at the transition point between these two phases /// procedure PadAndSwitchToSqueezingPhase; /// /// ??? /// /// /// Pointer where the output will be stored in /// /// /// State to work on /// /// /// Number of iterations /// procedure ExtractFromState(Outp: Pointer; const State: TState_L; LaneCount: Integer); /// /// Update final bits in LSB format, pad them, and compute the hash value /// /// /// Value used for padding if the length of the message to be hashed /// is not a multiple of 8 bit bytes. /// /// /// Number of needed padding bits? /// /// /// The hash value which shall be updated by this method /// procedure FinalBit_LSB(Bits: Byte; Bitlen: UInt16; var HashValue: TSHA3Digest); strict protected /// /// Contains the current state of the algorithms sponge part /// FSpongeState : TSpongeState; /// /// Initializes the state of the Keccak/SHA3 sponge function. It is set to /// the absorbing phase by this. If invalid parameter values are specified /// a EDECHashException will be raised /// /// /// Block length of the message to be processed, depends directly on the /// SHA3 variant (224, 256...) to be used /// /// /// Capacity c (it could directly be calculated from the rate as /// c = 1600 - r but the original author Wolfgang Erhardt decided against /// this. /// The capacity is the size of that part of the state vector which, when /// xored with the message blocks and when extracting the resulting hash, /// stays untouched. /// procedure InitSponge(Rate, Capacity: UInt16); /// /// Init internal data /// procedure DoInit; override; /// /// Dummy method to avoid the compiler warning about a class with abstract method /// procedure DoTransform(Buffer: PUInt32Array); override; /// /// Final step of the calculation /// procedure DoDone; override; public /// /// Processes one chunk of data to be hashed. /// /// /// Data on which the hash value shall be calculated on /// /// /// Size of the data in bytes /// procedure Calc(const Data; DataSize: Integer); override; /// /// Returns the calculated hash value /// /// /// Hash value calculated /// function Digest: PByteArray; override; end; /// /// 224 bit SHA3 variant /// THash_SHA3_224 = class(THash_SHA3Base) protected procedure DoInit; override; public class function BlockSize: UInt32; override; class function DigestSize: UInt32; override; end; /// /// 256 bit SHA3 variant /// THash_SHA3_256 = class(THash_SHA3Base) protected procedure DoInit; override; public class function BlockSize: UInt32; override; class function DigestSize: UInt32; override; end; /// /// 384 bit SHA3 variant /// THash_SHA3_384 = class(THash_SHA3Base) protected procedure DoInit; override; public class function BlockSize: UInt32; override; class function DigestSize: UInt32; override; end; /// /// 512 bit SHA3 variant /// THash_SHA3_512 = class(THash_SHA3Base) protected procedure DoInit; override; public class function BlockSize: UInt32; override; class function DigestSize: UInt32; override; end; THavalBaseTransformMethod = procedure(Buffer: PUInt32Array) of object; THashBaseHaval = class(TDECHashAuthentication) private FDigest: array[0..7] of UInt32; FRounds: UInt32; FTransform: THavalBaseTransformMethod; procedure SetRounds(Value: UInt32); protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; procedure DoTransform3(Buffer: PUInt32Array); procedure DoTransform4(Buffer: PUInt32Array); procedure DoTransform5(Buffer: PUInt32Array); procedure DoDone; override; public function Digest: PByteArray; override; class function BlockSize: UInt32; override; /// Returns the minimum possible number for the rounds parameter. /// Value depends on Digest size which depends on concrete implementation /// class function GetMinRounds: UInt8; /// /// Returns the maximum possible number for the rounds parameter. /// Value depends on Digest size which depends on concrete implementation /// class function GetMaxRounds: UInt8; /// /// Defines the number of rounds the algorithm performs on the input data. /// The range for this parameter is 3-5 rounds. If a value outside this /// range is assigned, the value used depends on the DigestSize. For /// DigestSizes <= 20 it will be set to 3, for values <= 28 to 4 and for /// bigger values to 5. For 3 rounds the algorithm is considered unsafe, /// as in 2003 collisions could be found with a setting of 3 rounds only. /// property Rounds: UInt32 read FRounds write SetRounds default 3; end; /// /// In 2004 collisions for this one were found, so this one should be /// considered to be unsafe. /// THash_Haval128 = class(THashBaseHaval) public class function DigestSize: UInt32; override; end; THash_Haval160 = class(THashBaseHaval) public class function DigestSize: UInt32; override; end; THash_Haval192 = class(THashBaseHaval) public class function DigestSize: UInt32; override; end; THash_Haval224 = class(THashBaseHaval) public class function DigestSize: UInt32; override; end; THash_Haval256 = class(THashBaseHaval) public class function DigestSize: UInt32; override; end; /// /// This is actually an implementation of the 192 bit variant of the Tiger /// hash algorithm with 3 rounds, unless a different value is assigned /// to the rounds property. It is considered to be unsafe at least in the /// 192 Bit variant! /// THash_Tiger = class(THashBaseMD4) private const /// /// Minimum number of rounds for the Tigher hash function. Trying to set a /// lower one sets the rounds to this value. /// cTigerMinRounds = 3; /// /// Maximum number of rounds for the Tigher hash function. Trying to set a /// higher one sets the rounds to this value. /// cTigerMaxRounds = 32; var FRounds: Integer; procedure SetRounds(Value: Integer); protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; /// /// Returns the minimum possible number for the rounds parameter /// class function GetMinRounds: UInt8; /// /// Returns the maximum possible number for the rounds parameter /// class function GetMaxRounds: UInt8; /// /// Defines the number of rounds the algorithm will perform on the data /// passed. Valid values are in the range from 3-32 rounds and values /// outside this range will lead to a rounds value of 3 or 32 to be used, /// depending on whether a lower or higher value has been given. /// property Rounds: Integer read FRounds write SetRounds default 3; end; /// /// As there seem to exist 128 and 160 bit variants of Tiger, which seem to /// be truncated variants of Tiger 192, but we want to keep compatibility /// with old code we introduce an alias for the time being. /// It is considered to be unsafe at least in the 192 Bit variant! /// THash_Tiger192 = THash_Tiger; /// /// The Panama algorithm is being considered to be unsafe. Support is only /// being provided for backward compatibility. /// THash_Panama = class(TDECHashAuthentication) private FLFSRBuffer: array[0..31, 0..7] of UInt32; FDigest: array[0..16] of UInt32; FTap: UInt32; protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; procedure DoDone; override; procedure DoPull; public function Digest: PByteArray; override; class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; // 32 end; THashBaseWhirlpool = class(TDECHashAuthentication) private FDigest: array[0..15] of UInt32; FTableC: Pointer; FTableR: Pointer; protected procedure DoTransform(Buffer: PUInt32Array); override; procedure DoDone; override; public function Digest: PByteArray; override; class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; end; /// /// This is the original variant of the algorithmus. Do not use it as some /// security flaw has been detected early on by its inventors. DEC contains /// it for backwards compatibility and completeness. /// THash_Whirlpool0 = class(THashBaseWhirlpool) protected procedure DoInit; override; end; /// /// This is variant of the algorithmus fixing the security flaw of the /// original version Whirlpool0. Do not use it in new code as it has been /// superseeded by the optimized Whirlpool1 (THash_Whirlpool1 class in DEC) /// variant which is additionally more safe as well! It is there for /// backwards compatibility and completeness only. /// THash_WhirlpoolT = class(THashBaseWhirlpool) protected procedure DoInit; override; end; /// /// The current version of Whirlpool but not the one used in code developed /// against the older DEC 5.x versions. The name of the one used in your /// code differs, depending whether you opt tu use the old DEC 5.2 compatible /// class names where the name Whirlpool1 was already taken by the variant /// nowadays known as Whirlpool-T. /// THash_Whirlpool1_ = class(THashBaseWhirlpool) protected procedure DoInit; override; end; {$IFDEF OLD_WHIRLPOOL_NAMES} /// /// This is the original variant of the algorithmus. Do not use it as some /// security flaw has been detected early on by its inventors. DEC contains /// it for backwards compatibility and completeness. /// THash_Whirlpool = class(THash_Whirlpool0); /// /// This is variant of the algorithmus fixing the security flaw of the /// original version Whirlpool0. Do not use it in new code as it has been /// superseeded by the optimized Whirlpool1 (THash_Whirlpool1 class in DEC) /// variant which is additionally more safe as well! It is there for /// backwards compatibility and completeness only. /// THash_Whirlpool1 = class(THash_WhirlpoolT); /// /// The current version of Whirlpool but not the one used in code developed /// against the older DEC 5.x versions. The name of the one used in your /// code differs, depending whether you opt tu use the old DEC 5.2 compatible /// class names where the name Whirlpool1 was already taken by the variant /// nowadays known as Whirlpool-T. /// THash_Whirlpool1New = class(THash_Whirlpool1_); {$ELSE} /// /// The current version of Whirlpool but not the one used in code developed /// against the older DEC 5.x versions. The name of the one used in your /// code differs, depending whether you opt tu use the old DEC 5.2 compatible /// class names where the name Whirlpool1 was already taken by the variant /// nowadays known as Whirlpool-T. /// THash_Whirlpool1 = class(THash_Whirlpool1_); {$ENDIF} THash_Square = class(TDECHashAuthentication) private FDigest: array[0..3] of UInt32; protected procedure DoInit; override; procedure DoTransform(Buffer: PUInt32Array); override; procedure DoDone; override; public function Digest: PByteArray; override; class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; end; /// /// This 1990 developed hash function was named after the Egyptian Pharaoh /// Sneferu. Be sure to set SecurityLevel to at least 8. See remark there. /// THashBaseSnefru = class(TDECHashAuthentication) private FDigest: array[0..23] of UInt32; /// /// Number of rounds the loop will do on the data /// FRounds: Integer; /// /// Sets the number of rounds for the looping over the data /// procedure SetRounds(Value: Integer); protected procedure DoInit; override; procedure DoDone; override; public function Digest: PByteArray; override; /// Returns the minimum possible number for the rounds parameter. /// Value depends on Digest size which depends on concrete implementation /// class function GetMinRounds: UInt8; /// Returns the maximum possible number for the rounds parameter. /// Value depends on Digest size which depends on concrete implementation /// class function GetMaxRounds: UInt8; /// /// Can be set from 2 to 8, default is 8. This is the number of rounds the /// algorithm will use. With the default of 8 rounds it is being considered /// as safe as of spring 2016, with less rounds this algorithm is considered /// to be unsafe and even with 8 rounds it is not really strong. /// property Rounds: Integer read FRounds write SetRounds; end; /// /// This 1990 developed hash function was named after the Egyptian Pharaoh /// Sneferu. Be sure to set SecurityLevel to at least 8. See remark for /// THashBaseSnefru.SecurityLevel. /// THash_Snefru128 = class(THashBaseSnefru) protected procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; // 48 end; /// /// This 1990 developed hash function was named after the Egyptian Pharaoh /// Sneferu. Be sure to set SecurityLevel to at least 8. See remark /// THashBaseSnefru.SecurityLevel. /// THash_Snefru256 = class(THashBaseSnefru) protected procedure DoTransform(Buffer: PUInt32Array); override; public class function DigestSize: UInt32; override; class function BlockSize: UInt32; override; // 32 end; THash_Sapphire = class(TDECHashAuthentication) private FCards: array[0..255] of UInt32; FDigest: array[0..15] of UInt32; FRotor: UInt32; FRatchet: UInt32; FAvalanche: UInt32; FPlain: UInt32; FCipher: UInt32; FDigestSize: UInt8; /// /// Set the length of the output hash value in byte. /// /// /// Minimum value is 1 byte, maximum value is 64 byte = 512 bit. /// Sets the size to the default size returned by DigestSize otherwise. /// is specified. /// procedure SetDigestSize(Value: UInt8); protected procedure DoInit; override; procedure DoDone; override; procedure DoTransform(Buffer: PUInt32Array); override; public function Digest: PByteArray; override; function DigestAsBytes: TBytes; override; /// /// Returns the default digest/hash size in bit. If RequestedDigestSize is /// not set, the defauilt size returned here is being used. /// class function DigestSize: UInt32; override; /// /// Returns on which block size this algorithm operates. Since the Sapphire /// hash originates from a Sapphire stream cipher algorithm this is always 1. /// class function BlockSize: UInt32; override; procedure Calc(const Data; DataSize: Integer); override; /// /// This property defines the length of the output from the hash calculation /// in byte. The maximum value is 64 byte = 512 bit. Values bigger 64 byte /// and a value of 0 lead to the default size returned by DigestSize otherwise. /// This setting is only respected by the DigestAsBytes method and all other /// convenience methods using that one like CalcStream, CalcString, /// DigestAsString or DigestAsRawString. /// property RequestedDigestSize: UInt8 read FDigestSize write SetDigestSize; end; implementation uses DECData, DECDataHash; {$IFOPT Q+}{$DEFINE RESTORE_OVERFLOWCHECKS}{$Q-}{$ENDIF} {$IFOPT R+}{$DEFINE RESTORE_RANGECHECKS}{$R-}{$ENDIF} {$IFDEF X86ASM} {$DEFINE INCLUDED} // allows having the DECHash.inc in the IDE's project manager {$INCLUDE DECHash.asm86.inc} {$ENDIF !X86ASM} { Speed comparison of ASM vs. PurePascal Implementation. Valid only for Win32 compiler and this was for DEC 5.1 and thus compiler versions < D2009! assembler pascal THash_SHA512 : 85.1 cycles/byte 17.62 Mb/sec 220.9 cycles/byte 6.79 Mb/sec 159% THash_SHA384 : 85.2 cycles/byte 17.61 Mb/sec 220.0 cycles/byte 6.82 Mb/sec 158% THash_Tiger : 24.6 cycles/byte 60.98 Mb/sec 60.7 cycles/byte 24.69 Mb/sec 147% THash_Haval128 : 13.3 cycles/byte 112.55 Mb/sec 26.0 cycles/byte 57.77 Mb/sec 95% THash_SHA1 : 20.1 cycles/byte 74.80 Mb/sec 36.1 cycles/byte 41.51 Mb/sec 80% THash_SHA : 20.0 cycles/byte 75.03 Mb/sec 35.5 cycles/byte 42.21 Mb/sec 78% THash_Haval160 : 13.2 cycles/byte 113.30 Mb/sec 22.7 cycles/byte 66.12 Mb/sec 71% THash_Haval256 : 25.9 cycles/byte 57.84 Mb/sec 40.5 cycles/byte 37.07 Mb/sec 56% THash_Snefru128 : 159.7 cycles/byte 9.39 Mb/sec 248.2 cycles/byte 6.04 Mb/sec 55% THash_Snefru256 : 239.3 cycles/byte 6.27 Mb/sec 367.9 cycles/byte 4.08 Mb/sec 54% THash_RipeMD256 : 14.5 cycles/byte 103.16 Mb/sec 21.4 cycles/byte 70.08 Mb/sec 47% THash_MD4 : 5.8 cycles/byte 256.73 Mb/sec 8.5 cycles/byte 176.92 Mb/sec 45% THash_MD2 : 251.6 cycles/byte 5.96 Mb/sec 366.1 cycles/byte 4.10 Mb/sec 45% THash_RipeMD128 : 15.2 cycles/byte 98.89 Mb/sec 21.2 cycles/byte 70.61 Mb/sec 40% THash_RipeMD320 : 25.5 cycles/byte 58.73 Mb/sec 35.8 cycles/byte 41.87 Mb/sec 40% THash_MD5 : 8.9 cycles/byte 169.43 Mb/sec 11.4 cycles/byte 131.01 Mb/sec 29% THash_RipeMD160 : 26.5 cycles/byte 56.66 Mb/sec 31.4 cycles/byte 47.79 Mb/sec 19% THash_Square : 44.7 cycles/byte 33.58 Mb/sec 53.1 cycles/byte 28.23 Mb/sec 19% THash_Haval192 : 32.5 cycles/byte 46.17 Mb/sec 37.6 cycles/byte 39.87 Mb/sec 18% THash_WhirlpoolT: 104.9 cycles/byte 14.30 Mb/sec 122.8 cycles/byte 12.22 Mb/sec 17% THash_Whirlpool0: 104.7 cycles/byte 14.33 Mb/sec 119.9 cycles/byte 12.51 Mb/sec 15% THash_Sapphire : 52.9 cycles/byte 28.35 Mb/sec 53.8 cycles/byte 27.86 Mb/sec 2% THash_Haval224 : 32.0 cycles/byte 46.82 Mb/sec 32.3 cycles/byte 46.46 Mb/sec 1% THash_SHA256 : 47.8 cycles/byte 31.35 Mb/sec 47.8 cycles/byte 31.39 Mb/sec 0% THash_Panama : 8.9 cycles/byte 169.01 Mb/sec 7.3 cycles/byte 206.55 Mb/sec -18% } resourcestring /// /// Failure message when a hash algorithm is initialized with wrong parameters /// sHashInitFailure = 'Invalid %0:s algorithm initialization parameters specified: %1:s'; /// /// Failure message when absorb is callt with a bitlength not divideable by 8 /// without reminder or when it is called while already in squeezing state /// aSHA3AbsorbFailure = 'Absorb: number of bits mod 8 <> 0 or squeezing active. Bits: %0:d, '+ 'Squeezing: %1:s'; { THash_MD2 } {$IFNDEF THash_MD2_asm} procedure THash_MD2.DoTransform(Buffer: PUInt32Array); var I, J, T: UInt32; begin for I := 0 to 3 do begin PUInt32Array(@FDigest[16])[I] := Buffer[I]; PUInt32Array(@FDigest[32])[I] := PUInt32Array(@FDigest[0])[I] xor PUInt32Array(@FDigest[16])[I]; end; T := FDigest[63]; for I := 0 to 15 do begin T := FDigest[I + 48] xor MD2_PISubst[FDigest[I + 16] xor Byte(T)]; FDigest[I + 48] := Byte(T); end; T := 0; for I := 0 to 17 do begin for J := 0 to 47 do begin T := FDigest[J] xor MD2_PISubst[T]; FDigest[J] := Byte(T); end; T := (T + I) and $FF; end; end; {$ENDIF !THash_MD2_asm} procedure THash_MD2.DoInit; begin FillChar(FDigest, SizeOf(FDigest), 0); end; procedure THash_MD2.DoDone; var Remain: Integer; begin Remain := FBufferSize - FBufferIndex; FillChar(FBuffer[FBufferIndex], Remain, Remain); DoTransform(Pointer(FBuffer)); Move(FDigest[48], FBuffer^, FBufferSize); DoTransform(Pointer(FBuffer)); end; function THash_MD2.Digest: PByteArray; begin Result := @FDigest; end; class function THash_MD2.DigestSize: UInt32; begin Result := 16; end; class function THash_MD2.BlockSize: UInt32; begin Result := 16; end; { THashBaseMD4 } procedure THashBaseMD4.DoInit; begin FDigest[0] := $67452301; FDigest[1] := $EFCDAB89; FDigest[2] := $98BADCFE; FDigest[3] := $10325476; FDigest[4] := $C3D2E1F0; FDigest[5] := $76543210; FDigest[6] := $FEDCBA98; FDigest[7] := $89ABCDEF; FDigest[8] := $01234567; FDigest[9] := $3C2D1E0F; end; procedure THashBaseMD4.DoDone; begin if FCount[2] or FCount[3] <> 0 then RaiseHashOverflowError; if FPaddingByte = 0 then FPaddingByte := $80; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); if FBufferIndex > FBufferSize - 8 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); Move(FCount, FBuffer[FBufferSize - 8], 8); DoTransform(Pointer(FBuffer)); end; function THashBaseMD4.Digest: PByteArray; begin Result := @FDigest; end; class function THashBaseMD4.DigestSize: UInt32; begin Result := 16; end; class function THashBaseMD4.BlockSize: UInt32; begin Result := 64; end; { THash_MD4 } {$IFNDEF THash_MD4_asm} procedure THash_MD4.DoTransform(Buffer: PUInt32Array); const S1 = $5A827999; S2 = $6ED9EBA1; var A, B, C, D: UInt32; begin A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; Inc(A, B and C or not B and D + Buffer[ 0]); A := A shl 3 or A shr 29; Inc(D, A and B or not A and C + Buffer[ 1]); D := D shl 7 or D shr 25; Inc(C, D and A or not D and B + Buffer[ 2]); C := C shl 11 or C shr 21; Inc(B, C and D or not C and A + Buffer[ 3]); B := B shl 19 or B shr 13; Inc(A, B and C or not B and D + Buffer[ 4]); A := A shl 3 or A shr 29; Inc(D, A and B or not A and C + Buffer[ 5]); D := D shl 7 or D shr 25; Inc(C, D and A or not D and B + Buffer[ 6]); C := C shl 11 or C shr 21; Inc(B, C and D or not C and A + Buffer[ 7]); B := B shl 19 or B shr 13; Inc(A, B and C or not B and D + Buffer[ 8]); A := A shl 3 or A shr 29; Inc(D, A and B or not A and C + Buffer[ 9]); D := D shl 7 or D shr 25; Inc(C, D and A or not D and B + Buffer[10]); C := C shl 11 or C shr 21; Inc(B, C and D or not C and A + Buffer[11]); B := B shl 19 or B shr 13; Inc(A, B and C or not B and D + Buffer[12]); A := A shl 3 or A shr 29; Inc(D, A and B or not A and C + Buffer[13]); D := D shl 7 or D shr 25; Inc(C, D and A or not D and B + Buffer[14]); C := C shl 11 or C shr 21; Inc(B, C and D or not C and A + Buffer[15]); B := B shl 19 or B shr 13; Inc(A, B and C or B and D or C and D + Buffer[ 0] + S1); A := A shl 3 or A shr 29; Inc(D, A and B or A and C or B and C + Buffer[ 4] + S1); D := D shl 5 or D shr 27; Inc(C, D and A or D and B or A and B + Buffer[ 8] + S1); C := C shl 9 or C shr 23; Inc(B, C and D or C and A or D and A + Buffer[12] + S1); B := B shl 13 or B shr 19; Inc(A, B and C or B and D or C and D + Buffer[ 1] + S1); A := A shl 3 or A shr 29; Inc(D, A and B or A and C or B and C + Buffer[ 5] + S1); D := D shl 5 or D shr 27; Inc(C, D and A or D and B or A and B + Buffer[ 9] + S1); C := C shl 9 or C shr 23; Inc(B, C and D or C and A or D and A + Buffer[13] + S1); B := B shl 13 or B shr 19; Inc(A, B and C or B and D or C and D + Buffer[ 2] + S1); A := A shl 3 or A shr 29; Inc(D, A and B or A and C or B and C + Buffer[ 6] + S1); D := D shl 5 or D shr 27; Inc(C, D and A or D and B or A and B + Buffer[10] + S1); C := C shl 9 or C shr 23; Inc(B, C and D or C and A or D and A + Buffer[14] + S1); B := B shl 13 or B shr 19; Inc(A, B and C or B and D or C and D + Buffer[ 3] + S1); A := A shl 3 or A shr 29; Inc(D, A and B or A and C or B and C + Buffer[ 7] + S1); D := D shl 5 or D shr 27; Inc(C, D and A or D and B or A and B + Buffer[11] + S1); C := C shl 9 or C shr 23; Inc(B, C and D or C and A or D and A + Buffer[15] + S1); B := B shl 13 or B shr 19; Inc(A, B xor C xor D + Buffer[ 0] + S2); A := A shl 3 or A shr 29; Inc(D, A xor B xor C + Buffer[ 8] + S2); D := D shl 9 or D shr 23; Inc(C, D xor A xor B + Buffer[ 4] + S2); C := C shl 11 or C shr 21; Inc(B, C xor D xor A + Buffer[12] + S2); B := B shl 15 or B shr 17; Inc(A, B xor C xor D + Buffer[ 2] + S2); A := A shl 3 or A shr 29; Inc(D, A xor B xor C + Buffer[10] + S2); D := D shl 9 or D shr 23; Inc(C, D xor A xor B + Buffer[ 6] + S2); C := C shl 11 or C shr 21; Inc(B, C xor D xor A + Buffer[14] + S2); B := B shl 15 or B shr 17; Inc(A, B xor C xor D + Buffer[ 1] + S2); A := A shl 3 or A shr 29; Inc(D, A xor B xor C + Buffer[ 9] + S2); D := D shl 9 or D shr 23; Inc(C, D xor A xor B + Buffer[ 5] + S2); C := C shl 11 or C shr 21; Inc(B, C xor D xor A + Buffer[13] + S2); B := B shl 15 or B shr 17; Inc(A, B xor C xor D + Buffer[ 3] + S2); A := A shl 3 or A shr 29; Inc(D, A xor B xor C + Buffer[11] + S2); D := D shl 9 or D shr 23; Inc(C, D xor A xor B + Buffer[ 7] + S2); C := C shl 11 or C shr 21; Inc(B, C xor D xor A + Buffer[15] + S2); B := B shl 15 or B shr 17; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); end; {$ENDIF} { THash_MD5 } {$IFNDEF THash_MD5_asm} procedure THash_MD5.DoTransform(Buffer: PUInt32Array); var A, B, C, D: UInt32; begin A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; Inc(A, Buffer[ 0] + $D76AA478 + (D xor (B and (C xor D)))); A := A shl 7 or A shr 25 + B; Inc(D, Buffer[ 1] + $E8C7B756 + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A; Inc(C, Buffer[ 2] + $242070DB + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D; Inc(B, Buffer[ 3] + $C1BDCEEE + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C; Inc(A, Buffer[ 4] + $F57C0FAF + (D xor (B and (C xor D)))); A := A shl 7 or A shr 25 + B; Inc(D, Buffer[ 5] + $4787C62A + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A; Inc(C, Buffer[ 6] + $A8304613 + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D; Inc(B, Buffer[ 7] + $FD469501 + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C; Inc(A, Buffer[ 8] + $698098D8 + (D xor (B and (C xor D)))); A := A shl 7 or A shr 25 + B; Inc(D, Buffer[ 9] + $8B44F7AF + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A; Inc(C, Buffer[10] + $FFFF5BB1 + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D; Inc(B, Buffer[11] + $895CD7BE + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C; Inc(A, Buffer[12] + $6B901122 + (D xor (B and (C xor D)))); A := A shl 7 or A shr 25 + B; Inc(D, Buffer[13] + $FD987193 + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A; Inc(C, Buffer[14] + $A679438E + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D; Inc(B, Buffer[15] + $49B40821 + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C; Inc(A, Buffer[ 1] + $F61E2562 + (C xor (D and (B xor C)))); A := A shl 5 or A shr 27 + B; Inc(D, Buffer[ 6] + $C040B340 + (B xor (C and (A xor B)))); D := D shl 9 or D shr 23 + A; Inc(C, Buffer[11] + $265E5A51 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D; Inc(B, Buffer[ 0] + $E9B6C7AA + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C; Inc(A, Buffer[ 5] + $D62F105D + (C xor (D and (B xor C)))); A := A shl 5 or A shr 27 + B; Inc(D, Buffer[10] + $02441453 + (B xor (C and (A xor B)))); D := D shl 9 or D shr 23 + A; Inc(C, Buffer[15] + $D8A1E681 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D; Inc(B, Buffer[ 4] + $E7D3FBC8 + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C; Inc(A, Buffer[ 9] + $21E1CDE6 + (C xor (D and (B xor C)))); A := A shl 5 or A shr 27 + B; Inc(D, Buffer[14] + $C33707D6 + (B xor (C and (A xor B)))); D := D shl 9 or D shr 23 + A; Inc(C, Buffer[ 3] + $F4D50D87 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D; Inc(B, Buffer[ 8] + $455A14ED + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C; Inc(A, Buffer[13] + $A9E3E905 + (C xor (D and (B xor C)))); A := A shl 5 or A shr 27 + B; Inc(D, Buffer[ 2] + $FCEFA3F8 + (B xor (C and (A xor B)))); D := D shl 9 or D shr 23 + A; Inc(C, Buffer[ 7] + $676F02D9 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D; Inc(B, Buffer[12] + $8D2A4C8A + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C; Inc(A, Buffer[ 5] + $FFFA3942 + (B xor C xor D)); A := A shl 4 or A shr 28 + B; Inc(D, Buffer[ 8] + $8771F681 + (A xor B xor C)); D := D shl 11 or D shr 21 + A; Inc(C, Buffer[11] + $6D9D6122 + (D xor A xor B)); C := C shl 16 or C shr 16 + D; Inc(B, Buffer[14] + $FDE5380C + (C xor D xor A)); B := B shl 23 or B shr 9 + C; Inc(A, Buffer[ 1] + $A4BEEA44 + (B xor C xor D)); A := A shl 4 or A shr 28 + B; Inc(D, Buffer[ 4] + $4BDECFA9 + (A xor B xor C)); D := D shl 11 or D shr 21 + A; Inc(C, Buffer[ 7] + $F6BB4B60 + (D xor A xor B)); C := C shl 16 or C shr 16 + D; Inc(B, Buffer[10] + $BEBFBC70 + (C xor D xor A)); B := B shl 23 or B shr 9 + C; Inc(A, Buffer[13] + $289B7EC6 + (B xor C xor D)); A := A shl 4 or A shr 28 + B; Inc(D, Buffer[ 0] + $EAA127FA + (A xor B xor C)); D := D shl 11 or D shr 21 + A; Inc(C, Buffer[ 3] + $D4EF3085 + (D xor A xor B)); C := C shl 16 or C shr 16 + D; Inc(B, Buffer[ 6] + $04881D05 + (C xor D xor A)); B := B shl 23 or B shr 9 + C; Inc(A, Buffer[ 9] + $D9D4D039 + (B xor C xor D)); A := A shl 4 or A shr 28 + B; Inc(D, Buffer[12] + $E6DB99E5 + (A xor B xor C)); D := D shl 11 or D shr 21 + A; Inc(C, Buffer[15] + $1FA27CF8 + (D xor A xor B)); C := C shl 16 or C shr 16 + D; Inc(B, Buffer[ 2] + $C4AC5665 + (C xor D xor A)); B := B shl 23 or B shr 9 + C; Inc(A, Buffer[ 0] + $F4292244 + (C xor (B or not D))); A := A shl 6 or A shr 26 + B; Inc(D, Buffer[ 7] + $432AFF97 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A; Inc(C, Buffer[14] + $AB9423A7 + (A xor (D or not B))); C := C shl 15 or C shr 17 + D; Inc(B, Buffer[ 5] + $FC93A039 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C; Inc(A, Buffer[12] + $655B59C3 + (C xor (B or not D))); A := A shl 6 or A shr 26 + B; Inc(D, Buffer[ 3] + $8F0CCC92 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A; Inc(C, Buffer[10] + $FFEFF47D + (A xor (D or not B))); C := C shl 15 or C shr 17 + D; Inc(B, Buffer[ 1] + $85845DD1 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C; Inc(A, Buffer[ 8] + $6FA87E4F + (C xor (B or not D))); A := A shl 6 or A shr 26 + B; Inc(D, Buffer[15] + $FE2CE6E0 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A; Inc(C, Buffer[ 6] + $A3014314 + (A xor (D or not B))); C := C shl 15 or C shr 17 + D; Inc(B, Buffer[13] + $4E0811A1 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C; Inc(A, Buffer[ 4] + $F7537E82 + (C xor (B or not D))); A := A shl 6 or A shr 26 + B; Inc(D, Buffer[11] + $BD3AF235 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A; Inc(C, Buffer[ 2] + $2AD7D2BB + (A xor (D or not B))); C := C shl 15 or C shr 17 + D; Inc(B, Buffer[ 9] + $EB86D391 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); end; {$ENDIF} { THash_RipeMD128 } {$IFNDEF X86ASM} const RipeS1 = $5A827999; RipeS2 = $6ED9EBA1; RipeS3 = $8F1BBCDC; RipeS4 = $A953FD4E; RipeS5 = $50A28BE6; RipeS6 = $5C4DD124; RipeS7 = $6D703EF3; RipeS8 = $7A6D76E9; {$ENDIF !X86ASM} {$IFNDEF THash_RipeMD128_asm} procedure THash_RipeMD128.DoTransform(Buffer: PUInt32Array); var A1, B1, C1, D1: UInt32; A2, B2, C2, D2: UInt32; T: UInt32; begin A1 := FDigest[0]; B1 := FDigest[1]; C1 := FDigest[2]; D1 := FDigest[3]; A2 := FDigest[0]; B2 := FDigest[1]; C2 := FDigest[2]; D2 := FDigest[3]; Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 xor B1 xor C1 + Buffer[ 1]); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 xor D1 xor A1 + Buffer[ 3]); B1 := B1 shl 12 or B1 shr 20; Inc(A1, B1 xor C1 xor D1 + Buffer[ 4]); A1 := A1 shl 5 or A1 shr 27; Inc(D1, A1 xor B1 xor C1 + Buffer[ 5]); D1 := D1 shl 8 or D1 shr 24; Inc(C1, D1 xor A1 xor B1 + Buffer[ 6]); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 xor D1 xor A1 + Buffer[ 7]); B1 := B1 shl 9 or B1 shr 23; Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 xor B1 xor C1 + Buffer[ 9]); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 14 or C1 shr 18; Inc(B1, C1 xor D1 xor A1 + Buffer[11]); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 xor C1 xor D1 + Buffer[12]); A1 := A1 shl 6 or A1 shr 26; Inc(D1, A1 xor B1 xor C1 + Buffer[13]); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 xor A1 xor B1 + Buffer[14]); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 xor D1 xor A1 + Buffer[15]); B1 := B1 shl 8 or B1 shr 24; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS1); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 4] + RipeS1); D1 := D1 shl 6 or D1 shr 26; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[13] + RipeS1); C1 := C1 shl 8 or C1 shr 24; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[15] + RipeS1); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS1); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[12] + RipeS1); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS1); D1 := D1 shl 12 or D1 shr 20; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 9] + RipeS1); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 5] + RipeS1); B1 := B1 shl 9 or B1 shr 23; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 2] + RipeS1); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS1); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[11] + RipeS1); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 8] + RipeS1); B1 := B1 shl 12 or B1 shr 20; Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS2); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 or not B1 xor C1 + Buffer[10] + RipeS2); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 or not A1 xor B1 + Buffer[14] + RipeS2); C1 := C1 shl 6 or C1 shr 26; Inc(B1, C1 or not D1 xor A1 + Buffer[ 4] + RipeS2); B1 := B1 shl 7 or B1 shr 25; Inc(A1, B1 or not C1 xor D1 + Buffer[ 9] + RipeS2); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS2); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 or not D1 xor A1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); D1 := D1 shl 8 or D1 shr 24; Inc(C1, D1 or not A1 xor B1 + Buffer[ 0] + RipeS2); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 or not D1 xor A1 + Buffer[ 6] + RipeS2); B1 := B1 shl 6 or B1 shr 26; Inc(A1, B1 or not C1 xor D1 + Buffer[13] + RipeS2); A1 := A1 shl 5 or A1 shr 27; Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS2); D1 := D1 shl 12 or D1 shr 20; Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS2); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS2); B1 := B1 shl 5 or B1 shr 27; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS3); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 9] + RipeS3); D1 := D1 shl 12 or D1 shr 20; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS3); C1 := C1 shl 14 or C1 shr 18; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[10] + RipeS3); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS3); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS3); D1 := D1 shl 15 or D1 shr 17; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[12] + RipeS3); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS3); B1 := B1 shl 8 or B1 shr 24; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS3); A1 := A1 shl 9 or A1 shr 23; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS3); C1 := C1 shl 5 or C1 shr 27; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[15] + RipeS3); B1 := B1 shl 6 or B1 shr 26; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl 8 or A1 shr 24; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); D1 := D1 shl 6 or D1 shr 26; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); C1 := C1 shl 5 or C1 shr 27; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 2] + RipeS3); B1 := B1 shl 12 or B1 shr 20; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 5] + RipeS5); A1 := A1 shl 8 or A1 shr 24; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[14] + RipeS5); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS5); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 0] + RipeS5); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 9] + RipeS5); A1 := A1 shl 13 or A1 shr 19; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS5); D1 := D1 shl 15 or D1 shr 17; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS5); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS5); B1 := B1 shl 5 or B1 shr 27; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS5); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS5); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[15] + RipeS5); C1 := C1 shl 8 or C1 shr 24; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 8] + RipeS5); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS5); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS5); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS5); C1 := C1 shl 12 or C1 shr 20; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[12] + RipeS5); B1 := B1 shl 6 or B1 shr 26; Inc(A1, B1 or not C1 xor D1 + Buffer[ 6] + RipeS6); A1 := A1 shl 9 or A1 shr 23; Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 or not A1 xor B1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 or not D1 xor A1 + Buffer[ 7] + RipeS6); B1 := B1 shl 7 or B1 shr 25; Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20; Inc(D1, A1 or not B1 xor C1 + Buffer[13] + RipeS6); D1 := D1 shl 8 or D1 shr 24; Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS6); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 or not D1 xor A1 + Buffer[10] + RipeS6); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 or not C1 xor D1 + Buffer[14] + RipeS6); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS6); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS6); C1 := C1 shl 12 or C1 shr 20; Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS6); B1 := B1 shl 7 or B1 shr 25; Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS6); A1 := A1 shl 6 or A1 shr 26; Inc(D1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS6); D1 := D1 shl 15 or D1 shr 17; Inc(C1, D1 or not A1 xor B1 + Buffer[ 1] + RipeS6); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 or not D1 xor A1 + Buffer[ 2] + RipeS6); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[15] + RipeS7); A1 := A1 shl 9 or A1 shr 23; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS7); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 1] + RipeS7); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS7); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS7); A1 := A1 shl 8 or A1 shr 24; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS7); D1 := D1 shl 6 or D1 shr 26; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 6] + RipeS7); C1 := C1 shl 6 or C1 shr 26; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS7); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[12] + RipeS7); C1 := C1 shl 5 or C1 shr 27; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 2] + RipeS7); B1 := B1 shl 14 or B1 shr 18; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS7); A1 := A1 shl 13 or A1 shr 19; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS7); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 4] + RipeS7); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[13] + RipeS7); B1 := B1 shl 5 or B1 shr 27; Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 15 or A1 shr 17; Inc(D1, A1 xor B1 xor C1 + Buffer[ 6]); D1 := D1 shl 5 or D1 shr 27; Inc(C1, D1 xor A1 xor B1 + Buffer[ 4]); C1 := C1 shl 8 or C1 shr 24; Inc(B1, C1 xor D1 xor A1 + Buffer[ 1]); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 xor C1 xor D1 + Buffer[ 3]); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 xor B1 xor C1 + Buffer[11]); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 xor A1 xor B1 + Buffer[15]); C1 := C1 shl 6 or C1 shr 26; Inc(B1, C1 xor D1 xor A1 + Buffer[ 0]); B1 := B1 shl 14 or B1 shr 18; Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl 6 or A1 shr 26; Inc(D1, A1 xor B1 xor C1 + Buffer[12]); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 12 or C1 shr 20; Inc(B1, C1 xor D1 xor A1 + Buffer[13]); B1 := B1 shl 9 or B1 shr 23; Inc(A1, B1 xor C1 xor D1 + Buffer[ 9]); A1 := A1 shl 12 or A1 shr 20; Inc(D1, A1 xor B1 xor C1 + Buffer[ 7]); D1 := D1 shl 5 or D1 shr 27; Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 xor D1 xor A1 + Buffer[14]); B1 := B1 shl 8 or B1 shr 24; Inc(D1, C2 + FDigest[1]); FDigest[1] := FDigest[2] + D2 + A1; FDigest[2] := FDigest[3] + A2 + B1; FDigest[3] := FDIgest[0] + B2 + C1; FDigest[0] := D1; end; {$ENDIF !THash_RipeMD128_asm} { THash_RipeMD160 } {$IFNDEF THash_RipeMD160_asm} procedure THash_RipeMD160.DoTransform(Buffer: PUInt32Array); var A1, B1, C1, D1, E1: UInt32; A2, B2, C2, D2, E2: UInt32; T: UInt32; begin A1 := FDigest[0]; B1 := FDigest[1]; C1 := FDigest[2]; D1 := FDigest[3]; E1 := FDigest[4]; A2 := FDigest[0]; B2 := FDigest[1]; C2 := FDigest[2]; D2 := FDigest[3]; E2 := FDigest[4]; Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 1]); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 2]); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 3]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[ 4]); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 6]); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 7]); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 8]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[ 9]); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[10]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[11]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[12]); D1 := D1 shl 6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[13]); C1 := C1 shl 7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[14]); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS1); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 4] + RipeS1); D1 := D1 shl 6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[13] + RipeS1); C1 := C1 shl 8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[15] + RipeS1); D1 := D1 shl 7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 3] + RipeS1); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[12] + RipeS1); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS1); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 9] + RipeS1); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 5] + RipeS1); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS1); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[14] + RipeS1); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS1); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS1); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[ 3] + RipeS2); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[10] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[14] + RipeS2); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS2); A1 := A1 shl 7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS2); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS2); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); E1 := E1 shl 8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[ 0] + RipeS2); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS2); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[13] + RipeS2); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS2); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 5] + RipeS2); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS2); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 1] + RipeS3); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS3); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[11] + RipeS3); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS3); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 0] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 8] + RipeS3); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[12] + RipeS3); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 4] + RipeS3); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS3); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 7] + RipeS3); C1 := C1 shl 5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[15] + RipeS3); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); E1 := E1 shl 6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 2] + RipeS3); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 4] + RipeS4); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 0] + RipeS4); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[ 5] + RipeS4); E1 := E1 shl 5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 9] + RipeS4); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[ 7] + RipeS4); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[12] + RipeS4); B1 := B1 shl 8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS4); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[10] + RipeS4); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[14] + RipeS4); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[ 1] + RipeS4); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS4); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 8] + RipeS4); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS4); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 6] + RipeS4); D1 := D1 shl 8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[15] + RipeS4); C1 := C1 shl 5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[13] + RipeS4); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(A1, C1 or not D1 xor B1 + Buffer[ 5] + RipeS5); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[14] + RipeS5); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 7] + RipeS5); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[ 0] + RipeS5); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 9] + RipeS5); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS5); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS5); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 4] + RipeS5); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[13] + RipeS5); C1 := C1 shl 7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 6] + RipeS5); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[15] + RipeS5); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[ 8] + RipeS5); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 1] + RipeS5); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[10] + RipeS5); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS5); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[12] + RipeS5); A1 := A1 shl 6 or A1 shr 26 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS6); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 7] + RipeS6); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS6); E1 := E1 shl 8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 5] + RipeS6); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[10] + RipeS6); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[14] + RipeS6); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[15] + RipeS6); A1 := A1 shl 7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS6); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[12] + RipeS6); D1 := D1 shl 7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 4] + RipeS6); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS6); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS6); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS6); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS7); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 5] + RipeS7); C1 := C1 shl 7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS7); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS7); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS7); E1 := E1 shl 8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[14] + RipeS7); D1 := D1 shl 6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS7); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 8] + RipeS7); E1 := E1 shl 13 or E1 shr 19 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS7); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 2] + RipeS7); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[10] + RipeS7); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS7); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 4] + RipeS7); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[13] + RipeS7); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 8] + RipeS8); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 6] + RipeS8); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 4] + RipeS8); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 1] + RipeS8); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 3] + RipeS8); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[11] + RipeS8); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[15] + RipeS8); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS8); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS8); E1 := E1 shl 6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[12] + RipeS8); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS8); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[13] + RipeS8); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 9] + RipeS8); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS8); E1 := E1 shl 5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[10] + RipeS8); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[14] + RipeS8); C1 := C1 shl 8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[12]); B1 := B1 shl 8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl 5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[10]); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 4]); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 1]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[ 5]); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 7]); E1 := E1 shl 6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 6]); D1 := D1 shl 8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 2]); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[13]); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[14]); A1 := A1 shl 5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 0]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 3]); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 9]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[11]); B1 := B1 shl 11 or B1 shr 21 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(D1, C2 + FDigest[1]); FDigest[1] := FDigest[2] + D2 + E1; FDigest[2] := FDigest[3] + E2 + A1; FDigest[3] := FDigest[4] + A2 + B1; FDigest[4] := FDigest[0] + B2 + C1; FDigest[0] := D1; end; {$ENDIF !THash_RipeMD160_asm} class function THash_RipeMD160.DigestSize: UInt32; begin Result := 20; end; { THash_RipeMD256 } {$IFNDEF THash_RipeMD256_asm} procedure THash_RipeMD256.DoTransform(Buffer: PUInt32Array); var A1, B1, C1, D1: UInt32; A2, B2, C2, D2: UInt32; T: UInt32; begin A1 := FDigest[0]; B1 := FDigest[1]; C1 := FDigest[2]; D1 := FDigest[3]; A2 := FDigest[4]; B2 := FDigest[5]; C2 := FDigest[6]; D2 := FDigest[7]; Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 xor B1 xor C1 + Buffer[ 1]); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 xor D1 xor A1 + Buffer[ 3]); B1 := B1 shl 12 or B1 shr 20; Inc(A1, B1 xor C1 xor D1 + Buffer[ 4]); A1 := A1 shl 5 or A1 shr 27; Inc(D1, A1 xor B1 xor C1 + Buffer[ 5]); D1 := D1 shl 8 or D1 shr 24; Inc(C1, D1 xor A1 xor B1 + Buffer[ 6]); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 xor D1 xor A1 + Buffer[ 7]); B1 := B1 shl 9 or B1 shr 23; Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 xor B1 xor C1 + Buffer[ 9]); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 14 or C1 shr 18; Inc(B1, C1 xor D1 xor A1 + Buffer[11]); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 xor C1 xor D1 + Buffer[12]); A1 := A1 shl 6 or A1 shr 26; Inc(D1, A1 xor B1 xor C1 + Buffer[13]); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 xor A1 xor B1 + Buffer[14]); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 xor D1 xor A1 + Buffer[15]); B1 := B1 shl 8 or B1 shr 24; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 5] + RipeS5); A1 := A1 shl 8 or A1 shr 24; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[14] + RipeS5); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS5); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 0] + RipeS5); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 9] + RipeS5); A1 := A1 shl 13 or A1 shr 19; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS5); D1 := D1 shl 15 or D1 shr 17; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS5); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS5); B1 := B1 shl 5 or B1 shr 27; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS5); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS5); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[15] + RipeS5); C1 := C1 shl 8 or C1 shr 24; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 8] + RipeS5); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS5); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS5); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS5); C1 := C1 shl 12 or C1 shr 20; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[12] + RipeS5); B1 := B1 shl 6 or B1 shr 26; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS1); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 4] + RipeS1); D1 := D1 shl 6 or D1 shr 26; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[13] + RipeS1); C1 := C1 shl 8 or C1 shr 24; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[15] + RipeS1); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS1); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[12] + RipeS1); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS1); D1 := D1 shl 12 or D1 shr 20; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 9] + RipeS1); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 5] + RipeS1); B1 := B1 shl 9 or B1 shr 23; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 2] + RipeS1); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS1); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[11] + RipeS1); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 8] + RipeS1); B1 := B1 shl 12 or B1 shr 20; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 or not C1 xor D1 + Buffer[ 6] + RipeS6); A1 := A1 shl 9 or A1 shr 23; Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 or not A1 xor B1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 or not D1 xor A1 + Buffer[ 7] + RipeS6); B1 := B1 shl 7 or B1 shr 25; Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20; Inc(D1, A1 or not B1 xor C1 + Buffer[13] + RipeS6); D1 := D1 shl 8 or D1 shr 24; Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS6); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 or not D1 xor A1 + Buffer[10] + RipeS6); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 or not C1 xor D1 + Buffer[14] + RipeS6); A1 := A1 shl 7 or A1 shr 25; Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS6); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS6); C1 := C1 shl 12 or C1 shr 20; Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS6); B1 := B1 shl 7 or B1 shr 25; Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS6); A1 := A1 shl 6 or A1 shr 26; Inc(D1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS6); D1 := D1 shl 15 or D1 shr 17; Inc(C1, D1 or not A1 xor B1 + Buffer[ 1] + RipeS6); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 or not D1 xor A1 + Buffer[ 2] + RipeS6); B1 := B1 shl 11 or B1 shr 21; T := A1; A1 := A2; A2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS2); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 or not B1 xor C1 + Buffer[10] + RipeS2); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 or not A1 xor B1 + Buffer[14] + RipeS2); C1 := C1 shl 6 or C1 shr 26; Inc(B1, C1 or not D1 xor A1 + Buffer[ 4] + RipeS2); B1 := B1 shl 7 or B1 shr 25; Inc(A1, B1 or not C1 xor D1 + Buffer[ 9] + RipeS2); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS2); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 or not D1 xor A1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); D1 := D1 shl 8 or D1 shr 24; Inc(C1, D1 or not A1 xor B1 + Buffer[ 0] + RipeS2); C1 := C1 shl 13 or C1 shr 19; Inc(B1, C1 or not D1 xor A1 + Buffer[ 6] + RipeS2); B1 := B1 shl 6 or B1 shr 26; Inc(A1, B1 or not C1 xor D1 + Buffer[13] + RipeS2); A1 := A1 shl 5 or A1 shr 27; Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS2); D1 := D1 shl 12 or D1 shr 20; Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS2); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS2); B1 := B1 shl 5 or B1 shr 27; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[15] + RipeS7); A1 := A1 shl 9 or A1 shr 23; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS7); D1 := D1 shl 7 or D1 shr 25; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 1] + RipeS7); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS7); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS7); A1 := A1 shl 8 or A1 shr 24; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS7); D1 := D1 shl 6 or D1 shr 26; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 6] + RipeS7); C1 := C1 shl 6 or C1 shr 26; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS7); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[12] + RipeS7); C1 := C1 shl 5 or C1 shr 27; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 2] + RipeS7); B1 := B1 shl 14 or B1 shr 18; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS7); A1 := A1 shl 13 or A1 shr 19; Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS7); D1 := D1 shl 13 or D1 shr 19; Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 4] + RipeS7); C1 := C1 shl 7 or C1 shr 25; Inc(B1, C1 and D1 or not C1 and A1 + Buffer[13] + RipeS7); B1 := B1 shl 5 or B1 shr 27; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS3); A1 := A1 shl 11 or A1 shr 21; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 9] + RipeS3); D1 := D1 shl 12 or D1 shr 20; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS3); C1 := C1 shl 14 or C1 shr 18; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[10] + RipeS3); B1 := B1 shl 15 or B1 shr 17; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS3); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS3); D1 := D1 shl 15 or D1 shr 17; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[12] + RipeS3); C1 := C1 shl 9 or C1 shr 23; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS3); B1 := B1 shl 8 or B1 shr 24; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS3); A1 := A1 shl 9 or A1 shr 23; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS3); C1 := C1 shl 5 or C1 shr 27; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[15] + RipeS3); B1 := B1 shl 6 or B1 shr 26; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl 8 or A1 shr 24; Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); D1 := D1 shl 6 or D1 shr 26; Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); C1 := C1 shl 5 or C1 shr 27; Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 2] + RipeS3); B1 := B1 shl 12 or B1 shr 20; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 15 or A1 shr 17; Inc(D1, A1 xor B1 xor C1 + Buffer[ 6]); D1 := D1 shl 5 or D1 shr 27; Inc(C1, D1 xor A1 xor B1 + Buffer[ 4]); C1 := C1 shl 8 or C1 shr 24; Inc(B1, C1 xor D1 xor A1 + Buffer[ 1]); B1 := B1 shl 11 or B1 shr 21; Inc(A1, B1 xor C1 xor D1 + Buffer[ 3]); A1 := A1 shl 14 or A1 shr 18; Inc(D1, A1 xor B1 xor C1 + Buffer[11]); D1 := D1 shl 14 or D1 shr 18; Inc(C1, D1 xor A1 xor B1 + Buffer[15]); C1 := C1 shl 6 or C1 shr 26; Inc(B1, C1 xor D1 xor A1 + Buffer[ 0]); B1 := B1 shl 14 or B1 shr 18; Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl 6 or A1 shr 26; Inc(D1, A1 xor B1 xor C1 + Buffer[12]); D1 := D1 shl 9 or D1 shr 23; Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 12 or C1 shr 20; Inc(B1, C1 xor D1 xor A1 + Buffer[13]); B1 := B1 shl 9 or B1 shr 23; Inc(A1, B1 xor C1 xor D1 + Buffer[ 9]); A1 := A1 shl 12 or A1 shr 20; Inc(D1, A1 xor B1 xor C1 + Buffer[ 7]); D1 := D1 shl 5 or D1 shr 27; Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 15 or C1 shr 17; Inc(B1, C1 xor D1 xor A1 + Buffer[14]); B1 := B1 shl 8 or B1 shr 24; Inc(FDigest[0], A2); Inc(FDigest[1], B2); Inc(FDigest[2], C2); Inc(FDigest[3], D1); Inc(FDigest[4], A1); Inc(FDigest[5], B1); Inc(FDigest[6], C1); Inc(FDigest[7], D2); end; {$ENDIF !THash_RipeMD256_asm} procedure THash_RipeMD256.DoInit; begin FDigest[0] := $67452301; FDigest[1] := $EFCDAB89; FDigest[2] := $98BADCFE; FDigest[3] := $10325476; FDigest[4] := $76543210; FDigest[5] := $FEDCBA98; FDigest[6] := $89ABCDEF; FDigest[7] := $01234567; FDigest[8] := $01234567; FDigest[9] := $3C2D1E0F; end; class function THash_RipeMD256.DigestSize: UInt32; begin Result := 32; end; { THash_RipeMD320 } {$IFNDEF THash_RipeMD320_asm} procedure THash_RipeMD320.DoTransform(Buffer: PUInt32Array); var A1, B1, C1, D1, E1: UInt32; A2, B2, C2, D2, E2: UInt32; T: UInt32; begin A1 := FDigest[0]; B1 := FDigest[1]; C1 := FDigest[2]; D1 := FDigest[3]; E1 := FDigest[4]; A2 := FDigest[5]; B2 := FDigest[6]; C2 := FDigest[7]; D2 := FDigest[8]; E2 := FDigest[9]; Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 1]); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 2]); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 3]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[ 4]); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 6]); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 7]); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 8]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[ 9]); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[10]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[11]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[12]); D1 := D1 shl 6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[13]); C1 := C1 shl 7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[14]); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(A1, C1 or not D1 xor B1 + Buffer[ 5] + RipeS5); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[14] + RipeS5); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 7] + RipeS5); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[ 0] + RipeS5); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 9] + RipeS5); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS5); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS5); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 4] + RipeS5); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[13] + RipeS5); C1 := C1 shl 7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 6] + RipeS5); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[15] + RipeS5); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[ 8] + RipeS5); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 1] + RipeS5); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[10] + RipeS5); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS5); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[12] + RipeS5); A1 := A1 shl 6 or A1 shr 26 + E1; C1 := C1 shl 10 or C1 shr 22; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS1); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 4] + RipeS1); D1 := D1 shl 6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[13] + RipeS1); C1 := C1 shl 8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[15] + RipeS1); D1 := D1 shl 7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 3] + RipeS1); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[12] + RipeS1); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS1); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 9] + RipeS1); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 5] + RipeS1); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS1); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[14] + RipeS1); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS1); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS1); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS6); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 7] + RipeS6); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS6); E1 := E1 shl 8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 5] + RipeS6); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[10] + RipeS6); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[14] + RipeS6); B1 := B1 shl 7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[15] + RipeS6); A1 := A1 shl 7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS6); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[12] + RipeS6); D1 := D1 shl 7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 4] + RipeS6); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS6); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS6); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS6); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; T := A1; A1 := A2; A2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(D1, E1 or not A1 xor B1 + Buffer[ 3] + RipeS2); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[10] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[14] + RipeS2); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS2); A1 := A1 shl 7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS2); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS2); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); E1 := E1 shl 8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[ 0] + RipeS2); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS2); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[13] + RipeS2); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS2); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 5] + RipeS2); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS2); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS7); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 5] + RipeS7); C1 := C1 shl 7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS7); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS7); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS7); E1 := E1 shl 8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[14] + RipeS7); D1 := D1 shl 6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS7); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 8] + RipeS7); E1 := E1 shl 13 or E1 shr 19 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS7); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 or not E1 xor A1 + Buffer[ 2] + RipeS7); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 or not D1 xor E1 + Buffer[10] + RipeS7); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS7); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 or not B1 xor C1 + Buffer[ 4] + RipeS7); E1 := E1 shl 7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 or not A1 xor B1 + Buffer[13] + RipeS7); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 1] + RipeS3); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS3); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[11] + RipeS3); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS3); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 0] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 8] + RipeS3); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[12] + RipeS3); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 4] + RipeS3); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS3); E1 := E1 shl 9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 7] + RipeS3); C1 := C1 shl 5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and E1 or D1 and not E1 + Buffer[15] + RipeS3); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); E1 := E1 shl 6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 2] + RipeS3); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 8] + RipeS8); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 6] + RipeS8); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 4] + RipeS8); A1 := A1 shl 8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 1] + RipeS8); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 3] + RipeS8); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[11] + RipeS8); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[15] + RipeS8); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS8); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS8); E1 := E1 shl 6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[12] + RipeS8); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS8); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 and D1 or not C1 and E1 + Buffer[13] + RipeS8); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 9] + RipeS8); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS8); E1 := E1 shl 5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 and A1 or not E1 and B1 + Buffer[10] + RipeS8); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 and E1 or not D1 and A1 + Buffer[14] + RipeS8); C1 := C1 shl 8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := E1; E1 := E2; E2 := T; Inc(B1, D1 or not E1 xor C1 + Buffer[ 4] + RipeS4); B1 := B1 shl 9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 0] + RipeS4); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[ 5] + RipeS4); E1 := E1 shl 5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 9] + RipeS4); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[ 7] + RipeS4); C1 := C1 shl 6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[12] + RipeS4); B1 := B1 shl 8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS4); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[10] + RipeS4); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[14] + RipeS4); D1 := D1 shl 5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[ 1] + RipeS4); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS4); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, C1 or not D1 xor B1 + Buffer[ 8] + RipeS4); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS4); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, A1 or not B1 xor E1 + Buffer[ 6] + RipeS4); D1 := D1 shl 8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, E1 or not A1 xor D1 + Buffer[15] + RipeS4); C1 := C1 shl 5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, D1 or not E1 xor C1 + Buffer[13] + RipeS4); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; T := A1; A1 := A2; A2 := T; T := B1; B1 := B2; B2 := T; T := C1; C1 := C2; C2 := T; T := D1; D1 := D2; D2 := T; T := E1; E1 := E2; E2 := T; Inc(B1, C1 xor D1 xor E1 + Buffer[12]); B1 := B1 shl 8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl 5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[10]); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 4]); D1 := D1 shl 9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 1]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[ 5]); B1 := B1 shl 5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 7]); E1 := E1 shl 6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 6]); D1 := D1 shl 8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 2]); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[13]); B1 := B1 shl 6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(A1, B1 xor C1 xor D1 + Buffer[14]); A1 := A1 shl 5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22; Inc(E1, A1 xor B1 xor C1 + Buffer[ 0]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22; Inc(D1, E1 xor A1 xor B1 + Buffer[ 3]); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22; Inc(C1, D1 xor E1 xor A1 + Buffer[ 9]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22; Inc(B1, C1 xor D1 xor E1 + Buffer[11]); B1 := B1 shl 11 or B1 shr 21 + A1; D1 := D1 shl 10 or D1 shr 22; Inc(FDigest[0], A2); Inc(FDigest[1], B2); Inc(FDigest[2], C2); Inc(FDigest[3], D2); Inc(FDigest[4], E1); Inc(FDigest[5], A1); Inc(FDigest[6], B1); Inc(FDigest[7], C1); Inc(FDigest[8], D1); Inc(FDigest[9], E2); end; {$ENDIF !THash_RipeMD320_asm} class function THash_RipeMD320.DigestSize: UInt32; begin Result := 40; end; { THash_SHA } {$IFNDEF THash_SHA_asm} procedure THash_SHA0.DoTransform(Buffer: PUInt32Array); var A, B, C, D, E, T: UInt32; W: array[0..79] of UInt32; I: Integer; begin SwapUInt32Buffer(Buffer[0], W, 16); if ClassType <> THash_SHA1 then begin for I := 16 to 79 do begin T := W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16]; W[I] := T; end; end else begin for I := 16 to 79 do begin T := W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16]; W[I] := T shl 1 or T shr 31; end; end; A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; E := FDigest[4]; Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[ 0] + $5A827999); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[ 1] + $5A827999); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[ 2] + $5A827999); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[ 3] + $5A827999); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[ 4] + $5A827999); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[ 5] + $5A827999); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[ 6] + $5A827999); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[ 7] + $5A827999); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[ 8] + $5A827999); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[ 9] + $5A827999); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[10] + $5A827999); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[11] + $5A827999); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[12] + $5A827999); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[13] + $5A827999); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[14] + $5A827999); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[15] + $5A827999); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[16] + $5A827999); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[17] + $5A827999); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[18] + $5A827999); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[19] + $5A827999); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[20] + $6ED9EBA1); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[21] + $6ED9EBA1); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[22] + $6ED9EBA1); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[23] + $6ED9EBA1); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[24] + $6ED9EBA1); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[25] + $6ED9EBA1); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[26] + $6ED9EBA1); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[27] + $6ED9EBA1); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[28] + $6ED9EBA1); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[29] + $6ED9EBA1); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[30] + $6ED9EBA1); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[31] + $6ED9EBA1); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[32] + $6ED9EBA1); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[33] + $6ED9EBA1); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[34] + $6ED9EBA1); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[35] + $6ED9EBA1); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[36] + $6ED9EBA1); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[37] + $6ED9EBA1); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[38] + $6ED9EBA1); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[39] + $6ED9EBA1); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[40] + $8F1BBCDC); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[41] + $8F1BBCDC); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[42] + $8F1BBCDC); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[43] + $8F1BBCDC); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[44] + $8F1BBCDC); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[45] + $8F1BBCDC); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[46] + $8F1BBCDC); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[47] + $8F1BBCDC); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[48] + $8F1BBCDC); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[49] + $8F1BBCDC); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[50] + $8F1BBCDC); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[51] + $8F1BBCDC); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[52] + $8F1BBCDC); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[53] + $8F1BBCDC); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[54] + $8F1BBCDC); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[55] + $8F1BBCDC); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[56] + $8F1BBCDC); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[57] + $8F1BBCDC); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[58] + $8F1BBCDC); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[59] + $8F1BBCDC); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[60] + $CA62C1D6); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[61] + $CA62C1D6); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[62] + $CA62C1D6); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[63] + $CA62C1D6); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[64] + $CA62C1D6); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[65] + $CA62C1D6); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[66] + $CA62C1D6); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[67] + $CA62C1D6); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[68] + $CA62C1D6); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[69] + $CA62C1D6); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[70] + $CA62C1D6); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[71] + $CA62C1D6); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[72] + $CA62C1D6); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[73] + $CA62C1D6); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[74] + $CA62C1D6); C := C shr 2 or C shl 30; Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[75] + $CA62C1D6); B := B shr 2 or B shl 30; Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[76] + $CA62C1D6); A := A shr 2 or A shl 30; Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[77] + $CA62C1D6); E := E shr 2 or E shl 30; Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[78] + $CA62C1D6); D := D shr 2 or D shl 30; Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[79] + $CA62C1D6); C := C shr 2 or C shl 30; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); Inc(FDigest[4], E); end; {$ENDIF !THash_SHA_asm} procedure THash_SHA0.DoDone; begin if FCount[2] or FCount[3] <> 0 then RaiseHashOverflowError; if FPaddingByte = 0 then FPaddingByte := $80; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); if FBufferIndex > FBufferSize - 8 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); PUInt32(@FBuffer[FBufferSize - 8])^ := SwapUInt32(FCount[1]); PUInt32(@FBuffer[FBufferSize - 4])^ := SwapUInt32(FCount[0]); DoTransform(Pointer(FBuffer)); SwapUInt32Buffer(FDigest, FDigest, SizeOf(FDigest) div 4); end; class function THash_SHA0.DigestSize: UInt32; begin Result := 20; end; { THash_SHA256 } procedure THash_SHA256.DoInit; begin FDigest[0]:= $6A09E667; FDigest[1]:= $BB67AE85; FDigest[2]:= $3C6EF372; FDigest[3]:= $A54FF53A; FDigest[4]:= $510E527F; FDigest[5]:= $9B05688C; FDigest[6]:= $1F83D9AB; FDigest[7]:= $5BE0CD19; end; {$IFNDEF THash_SHA256_asm} procedure THash_SHA256.DoTransform(Buffer: PUInt32Array); var I: Integer; A, B, C, D, E, F, G, H: UInt32; T1, T2: UInt32; W: array[0..63] of UInt32; begin SwapUInt32Buffer(Buffer[0], W, 16); for I := 16 to 63 do begin T1 := W[I - 15]; T2 := W[I - 2]; W[I] := W[I - 16] + W[I - 7] + ((T1 shr 7 or T1 shl 25) xor (T1 shr 18 or T1 shl 14) xor (T1 shr 3)) + ((T2 shr 17 or T2 shl 15) xor (T2 shr 19 or T2 shl 13) xor (T2 shr 10)); end; // calculate new hash values A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; E := FDigest[4]; F := FDigest[5]; G := FDigest[6]; H := FDigest[7]; for I := 0 to 63 do begin T1 := ((E shr 6 or E shl 26) xor (E shr 11 or E shl 21) xor (E shr 25 or E shl 7)) + H + (((F xor G) and E) xor G) + SHA_256K[I] + W[I]; T2 := ((A shr 2 or A shl 30) xor (A shr 13 or A shl 19) xor (A shr 22 or A shl 10)) + (((B or C) and A) or (B and C)); H := G; G := F; F := E; E := D + T1; D := C; C := B; B := A; A := T1 + T2; end; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); Inc(FDigest[4], E); Inc(FDigest[5], F); Inc(FDigest[6], G); Inc(FDigest[7], H); end; {$ENDIF !THash_SHA256_asm} class function THash_SHA256.DigestSize: UInt32; begin Result := 32; end; { THash_SHA224 } class function THash_SHA224.BlockSize: UInt32; begin Result := 64; end; class function THash_SHA224.DigestSize: UInt32; begin Result := 28; end; procedure THash_SHA224.DoInit; begin FDigest[0]:= $C1059ED8; FDigest[1]:= $367CD507; FDigest[2]:= $3070DD17; FDigest[3]:= $F70E5939; FDigest[4]:= $FFC00B31; FDigest[5]:= $68581511; FDigest[6]:= $64F98FA7; FDigest[7]:= $BEFA4FA4; end; { THash_SHA384 } procedure THash_SHA384.DoInit; begin FDigest[0] := Int64($CBBB9D5DC1059ED8); FDigest[1] := Int64($629A292A367CD507); FDigest[2] := Int64($9159015A3070DD17); FDigest[3] := Int64($152FECD8F70E5939); FDigest[4] := Int64($67332667FFC00B31); FDigest[5] := Int64($8EB44A8768581511); FDigest[6] := Int64($DB0C2E0D64F98FA7); FDigest[7] := Int64($47B5481DBEFA4FA4); end; {$IFNDEF THash_SHA384_asm} procedure THash_SHA384.DoTransform(Buffer: PUInt32Array); var A, B, C, D, E, F, G, H: UInt64; T1, T2: UInt64; I: Integer; W: array [0..79] of UInt64; begin { TODO : The array passed is a UInt32 array, which doesn't fit with the name of this method!} SwapInt64Buffer(Buffer[0], W, 16); // calculate other 64 uint64 for I := 16 to 79 do begin T1 := W[I - 15]; T2 := W[I - 2]; W[I] := W[I - 16] + W[I - 7] + ((T1 shr 1 or T1 shl 63) xor (T1 shr 8 or T1 shl 56) xor (T1 shr 7)) + ((T2 shr 19 or T2 shl 45) xor (T2 shr 61 or T2 shl 3) xor (T2 shr 6)); end; // calculate new hash values A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; E := FDigest[4]; F := FDigest[5]; G := FDigest[6]; H := FDigest[7]; for I := 0 to 79 do begin T1 := ((E shr 14 or E shl 50) xor (E shr 18 or E shl 46) xor (E shr 41 or E shl 23)) + H + (((F xor G) and E) xor G) + SHA_512K[I] + W[I]; T2 := ((A shr 28 or A shl 36) xor (A shr 34 or A shl 30) xor (A shr 39 or A shl 25)) + (((B or C) and A) or (B and C)); H := G; G := F; F := E; E := D + T1; D := C; C := B; B := A; A := T1 + T2; end; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); Inc(FDigest[4], E); Inc(FDigest[5], F); Inc(FDigest[6], G); Inc(FDigest[7], H); end; {$ENDIF !THash_SHA384_asm} procedure THash_SHA384.DoDone; begin if FPaddingByte = 0 then FPaddingByte := $80; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); if FBufferIndex > FBufferSize - 16 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); SwapUInt32Buffer(FCount, FCount, 4); PUInt32(@FBuffer[FBufferSize - 16])^ := FCount[3]; PUInt32(@FBuffer[FBufferSize - 12])^ := FCount[2]; PUInt32(@FBuffer[FBufferSize - 8])^ := FCount[1]; PUInt32(@FBuffer[FBufferSize - 4])^ := FCount[0]; DoTransform(Pointer(FBuffer)); SwapInt64Buffer(FDigest, FDigest, SizeOf(FDigest) div 8); end; function THash_SHA384.Digest: PByteArray; begin Result := @FDigest; end; class function THash_SHA384.DigestSize: UInt32; begin Result := 48; end; class function THash_SHA384.BlockSize: UInt32; begin Result := 128; end; { THash_SHA512 } procedure THash_SHA512.DoInit; begin FDigest[0] := Int64($6A09E667F3BCC908); FDigest[1] := Int64($BB67AE8584CAA73B); FDigest[2] := Int64($3C6EF372FE94F82B); FDigest[3] := Int64($A54FF53A5F1D36F1); FDigest[4] := Int64($510E527FADE682D1); FDigest[5] := Int64($9B05688C2B3E6C1F); FDigest[6] := Int64($1F83D9ABFB41BD6B); FDigest[7] := Int64($5BE0CD19137E2179); end; class function THash_SHA512.DigestSize: UInt32; begin Result := 64; end; { THashBaseHaval } procedure THashBaseHaval.SetRounds(Value: UInt32); begin if (Value < 3) or (Value > 5) then begin if DigestSize <= 20 then Value := 3 else begin if DigestSize <= 28 then Value := 4 else Value := 5; end; end; FRounds := Value; case FRounds of 3: FTransform := DoTransform3; 4: FTransform := DoTransform4; 5: FTransform := DoTransform5; end; end; procedure THashBaseHaval.DoInit; begin SetRounds(FRounds); FDigest[0] := $243F6A88; FDigest[1] := $85A308D3; FDigest[2] := $13198A2E; FDigest[3] := $03707344; FDigest[4] := $A4093822; FDigest[5] := $299F31D0; FDigest[6] := $082EFA98; FDigest[7] := $EC4E6C89; end; procedure THashBaseHaval.DoTransform(Buffer: PUInt32Array); begin FTransform(Buffer); end; class function THashBaseHaval.GetMaxRounds: UInt8; begin Result := 5; end; class function THashBaseHaval.GetMinRounds: UInt8; begin if DigestSize <= 20 then Result := 3 else begin if DigestSize <= 28 then Result := 4 else Result := 5; end; end; {$IFNDEF THashBaseHaval_asm} procedure THashBaseHaval.DoTransform3(Buffer: PUInt32Array); var A, B, C, D, E, F, G, H, I, T: UInt32; Data: PUInt32; Offset: PByte; begin Offset := @Haval_Offset; Data := @Haval_Data; A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; E := FDigest[4]; F := FDigest[5]; G := FDigest[6]; H := FDigest[7]; for I := 0 to 31 do begin T := C and (E xor D) xor G and A xor F and B xor E; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[I]; H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := F and (D and not A xor B and C xor E xor G) xor B and (D xor C) xor A and C xor G; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := D and (F and E xor G xor A) xor F and C xor E and B xor A; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); Inc(FDigest[4], E); Inc(FDigest[5], F); Inc(FDigest[6], G); Inc(FDigest[7], H); end; procedure THashBaseHaval.DoTransform4(Buffer: PUInt32Array); var A, B, C, D, E, F, G, H, I, T: UInt32; Data: PUInt32; Offset: PByte; begin Offset := @Haval_Offset; Data := @Haval_Data; A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; E := FDigest[4]; F := FDigest[5]; G := FDigest[6]; H := FDigest[7]; for I := 0 to 31 do begin T := D and (A xor B) xor F and G xor E and C xor A; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[I]; H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := B and (G and not A xor C and F xor D xor E) xor C and (G xor F) xor A and F xor E; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := G and (C and A xor B xor F) xor C and D xor A and E xor F; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := A and (E and not C xor F and not G xor B xor G xor D) xor F and (B and C xor E xor G) xor C and G xor D; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); Inc(FDigest[4], E); Inc(FDigest[5], F); Inc(FDigest[6], G); Inc(FDigest[7], H); end; procedure THashBaseHaval.DoTransform5(Buffer: PUInt32Array); var A, B, C, D, E, F, G, H, I, T: UInt32; Data: PUInt32; Offset: PByte; begin Offset := @Haval_Offset; Data := @Haval_Data; A := FDigest[0]; B := FDigest[1]; C := FDigest[2]; D := FDigest[3]; E := FDigest[4]; F := FDigest[5]; G := FDigest[6]; H := FDigest[7]; for I := 0 to 31 do begin T := C and (G xor B) xor F and E xor A and D xor G; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[I]; H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := D and (E and not A xor B and C xor G xor F) xor B and (E xor C) xor A and C xor F; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := E and (B and D xor C xor F) xor B and A xor D and G xor F; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := D and (F and not A xor C and not B xor E xor B xor G) xor C and (E and A xor F xor B) xor A and B xor G; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; for I := 0 to 31 do begin T := B and (D and E and G xor not F) xor D and A xor E and F xor G and C; T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^; Inc(Offset); Inc(Data); H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T; end; Inc(FDigest[0], A); Inc(FDigest[1], B); Inc(FDigest[2], C); Inc(FDigest[3], D); Inc(FDigest[4], E); Inc(FDigest[5], F); Inc(FDigest[6], G); Inc(FDigest[7], H); end; {$ENDIF !THashBaseHaval_asm} procedure THashBaseHaval.DoDone; function ROR(Value, Count: UInt32): UInt32; {$IFDEF X86ASM} asm MOV ECX,EDX ROR EAX,CL end; {$ELSE !X86ASM} begin Result := (Value shr Count) or (Value shl (32 - Count)); end; {$ENDIF !X86ASM} var T: Word; begin if FCount[2] or FCount[3] <> 0 then RaiseHashOverflowError; if FPaddingByte = 0 then FPaddingByte := $01; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); if FBufferIndex > FBufferSize - 10 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex - 10, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex - 10, 0); T := DigestSize shl 9 or FRounds shl 3 or 1; Move(T, FBuffer[FBufferSize - 10], SizeOf(T)); Move(FCount, FBuffer[FBufferSize - 8], 8); DoTransform(Pointer(FBuffer)); case DigestSize of 16: begin Inc(FDigest[0], ROR(FDigest[7] and $000000FF or FDigest[6] and $FF000000 or FDigest[5] and $00FF0000 or FDigest[4] and $0000FF00, 8)); Inc(FDigest[1], ROR(FDigest[7] and $0000FF00 or FDigest[6] and $000000FF or FDigest[5] and $FF000000 or FDigest[4] and $00FF0000, 16)); Inc(FDigest[2], ROR(FDigest[7] and $00FF0000 or FDigest[6] and $0000FF00 or FDigest[5] and $000000FF or FDigest[4] and $FF000000, 24)); Inc(FDigest[3], FDigest[7] and $FF000000 or FDigest[6] and $00FF0000 or FDigest[5] and $0000FF00 or FDigest[4] and $000000FF); end; 20: begin Inc(FDigest[0], ROR(FDigest[7] and ($3F) or FDigest[6] and ($7F shl 25) or FDigest[5] and ($3F shl 19), 19)); Inc(FDigest[1], ROR(FDigest[7] and ($3F shl 6) or FDigest[6] and ($3F) or FDigest[5] and ($7F shl 25), 25)); Inc(FDigest[2], FDigest[7] and ($7F shl 12) or FDigest[6] and ($3F shl 6) or FDigest[5] and ($3F)); Inc(FDigest[3], (FDigest[7] and ($3F shl 19) or FDigest[6] and ($7F shl 12) or FDigest[5] and ($3F shl 6)) shr 6); Inc(FDigest[4], (FDigest[7] and ($7F shl 25) or FDigest[6] and ($3F shl 19) or FDigest[5] and ($7F shl 12)) shr 12); end; 24: begin Inc(FDigest[0], ROR(FDigest[7] and ($1F) or FDigest[6] and ($3F shl 26), 26)); Inc(FDigest[1], FDigest[7] and ($1F shl 5) or FDigest[6] and ($1F)); Inc(FDigest[2], (FDigest[7] and ($3F shl 10) or FDigest[6] and ($1F shl 5)) shr 5); Inc(FDigest[3], (FDigest[7] and ($1F shl 16) or FDigest[6] and ($3F shl 10)) shr 10); Inc(FDigest[4], (FDigest[7] and ($1F shl 21) or FDigest[6] and ($1F shl 16)) shr 16); Inc(FDigest[5], (FDigest[7] and ($3F shl 26) or FDigest[6] and ($1F shl 21)) shr 21); end; 28: begin Inc(FDigest[0], FDigest[7] shr 27 and $1F); Inc(FDigest[1], FDigest[7] shr 22 and $1F); Inc(FDigest[2], FDigest[7] shr 18 and $0F); Inc(FDigest[3], FDigest[7] shr 13 and $1F); Inc(FDigest[4], FDigest[7] shr 9 and $0F); Inc(FDigest[5], FDigest[7] shr 4 and $1F); Inc(FDigest[6], FDigest[7] and $0F); end; end; end; function THashBaseHaval.Digest: PByteArray; begin Result := @FDigest; end; class function THashBaseHaval.BlockSize: UInt32; begin Result := 128; end; { THash_Haval128 } class function THash_Haval128.DigestSize: UInt32; begin Result := 16; end; { THash_Haval160 } class function THash_Haval160.DigestSize: UInt32; begin Result := 20; end; { THash_Haval192 } class function THash_Haval192.DigestSize: UInt32; begin Result := 24; end; { THash_Haval224 } class function THash_Haval224.DigestSize: UInt32; begin Result := 28; end; { THash_Haval256 } class function THash_Haval256.DigestSize: UInt32; begin Result := 32; end; { THash_Tiger } procedure THash_Tiger.SetRounds(Value: Integer); begin if (Value < cTigerMinRounds) then Value := cTigerMinRounds; if (Value > cTigerMaxRounds) then Value := cTigerMaxRounds; FRounds := Value; end; procedure THash_Tiger.DoInit; begin SetRounds(FRounds); if FPaddingByte = 0 then FPaddingByte := $01; FDigest[0] := $89ABCDEF; FDigest[1] := $01234567; FDigest[2] := $76543210; FDigest[3] := $FEDCBA98; FDigest[4] := $C3B2E187; FDigest[5] := $F096A5B4; end; procedure THash_Tiger.DoTransform(Buffer: PUInt32Array); type PTiger_Data = ^TTiger_Data; TTiger_Data = array[0..3, 0..255] of Int64; PInt64Array = ^TInt64Array; TInt64Array = array[0..7] of Int64; var A, B, C, T: Int64; x0, x1, x2, x3, x4, x5, x6, x7: UInt64; I: Integer; begin A := PInt64Array(@FDigest)[0]; B := PInt64Array(@FDigest)[1]; C := PInt64Array(@FDigest)[2]; x0 := PInt64Array(Buffer)[0]; x1 := PInt64Array(Buffer)[1]; x2 := PInt64Array(Buffer)[2]; x3 := PInt64Array(Buffer)[3]; x4 := PInt64Array(Buffer)[4]; x5 := PInt64Array(Buffer)[5]; x6 := PInt64Array(Buffer)[6]; x7 := PInt64Array(Buffer)[7]; for I := 1 to FRounds do // a Loop is faster for PC with small Cache begin if I > 1 then // Key Schedule begin Dec(x0, x7 xor $A5A5A5A5A5A5A5A5); x1 := x1 xor x0; Inc(x2, x1); Dec(x3, x2 xor (not x1 shl 19)); x4 := x4 xor x3; Inc(x5, x4); Dec(x6, x5 xor (not x4 shr 23)); x7 := x7 xor x6; Inc(x0, x7); Dec(x1, x0 xor (not x7 shl 19)); x2 := x2 xor x1; Inc(x3, x2); Dec(x4, x3 xor (not x2 shr 23)); x5 := x5 xor x4; Inc(x6, x5); Dec(x7, x6 xor $0123456789ABCDEF); end; C := C xor x0; Dec(A, TTiger_Data(Tiger_Data)[0, UInt32(C) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(C) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, C shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(C shr 32) shr 16 and $FF]); Inc(B, TTiger_Data(Tiger_Data)[3, UInt32(C) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(C) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(C shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(C shr 32) shr 24]); if I = 1 then B := B shl 2 + B else begin if I = 2 then B := B shl 3 - B else B := B shl 3 + B; end; A := A xor x1; Dec(B, TTiger_Data(Tiger_Data)[0, UInt32(A) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(A) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, A shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(A shr 32) shr 16 and $FF]); Inc(C, TTiger_Data(Tiger_Data)[3, UInt32(A) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(A) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(A shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(A shr 32) shr 24]); if I = 1 then C := C shl 2 + C else begin if I = 2 then C := C shl 3 - C else C := C shl 3 + C; end; B := B xor x2; Dec(C, TTiger_Data(Tiger_Data)[0, UInt32(B) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(B) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, B shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(B shr 32) shr 16 and $FF]); Inc(A, TTiger_Data(Tiger_Data)[3, UInt32(B) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(B) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(B shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(B shr 32) shr 24]); if I = 1 then A := A shl 2 + A else begin if I = 2 then A := A shl 3 - A else A := A shl 3 + A; end; C := C xor x3; Dec(A, TTiger_Data(Tiger_Data)[0, UInt32(C) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(C) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, C shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(C shr 32) shr 16 and $FF]); Inc(B, TTiger_Data(Tiger_Data)[3, UInt32(C) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(C) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(C shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(C shr 32) shr 24]); if I = 1 then B := B shl 2 + B else begin if I = 2 then B := B shl 3 - B else B := B shl 3 + B; end; A := A xor x4; Dec(B, TTiger_Data(Tiger_Data)[0, UInt32(A) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(A) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, A shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(A shr 32) shr 16 and $FF]); Inc(C, TTiger_Data(Tiger_Data)[3, UInt32(A) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(A) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(A shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(A shr 32) shr 24]); if I = 1 then C := C shl 2 + C else begin if I = 2 then C := C shl 3 - C else C := C shl 3 + C; end; B := B xor x5; Dec(C, TTiger_Data(Tiger_Data)[0, UInt32(B) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(B) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, B shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(B shr 32) shr 16 and $FF]); Inc(A, TTiger_Data(Tiger_Data)[3, UInt32(B) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(B) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(B shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(B shr 32) shr 24]); if I = 1 then A := A shl 2 + A else begin if I = 2 then A := A shl 3 - A else A := A shl 3 + A; end; C := C xor x6; Dec(A, TTiger_Data(Tiger_Data)[0, UInt32(C) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(C) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, C shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(C shr 32) shr 16 and $FF]); Inc(B, TTiger_Data(Tiger_Data)[3, UInt32(C) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(C) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(C shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(C shr 32) shr 24]); if I = 1 then B := B shl 2 + B else begin if I = 2 then B := B shl 3 - B else B := B shl 3 + B; end; A := A xor x7; Dec(B, TTiger_Data(Tiger_Data)[0, UInt32(A) and $FF] xor TTiger_Data(Tiger_Data)[1, UInt32(A) shr 16 and $FF] xor TTiger_Data(Tiger_Data)[2, A shr 32 and $FF] xor TTiger_Data(Tiger_Data)[3, UInt32(A shr 32) shr 16 and $FF]); Inc(C, TTiger_Data(Tiger_Data)[3, UInt32(A) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[2, UInt32(A) shr 24] xor TTiger_Data(Tiger_Data)[1, UInt32(A shr 32) shr 8 and $FF] xor TTiger_Data(Tiger_Data)[0, UInt32(A shr 32) shr 24]); if I = 1 then C := C shl 2 + C else begin if I = 2 then C := C shl 3 - C else C := C shl 3 + C; end; T := A; A := C; C := B; B := T; end; PInt64Array(@FDigest)[0] := A xor PInt64Array(@FDigest)[0]; PInt64Array(@FDigest)[1] := B - PInt64Array(@FDigest)[1]; PInt64Array(@FDigest)[2] := C + PInt64Array(@FDigest)[2]; end; class function THash_Tiger.GetMaxRounds: UInt8; begin Result := cTigerMaxRounds; end; class function THash_Tiger.GetMinRounds: UInt8; begin Result := cTigerMinRounds; end; class function THash_Tiger.DigestSize: UInt32; begin Result := 24; end; { THash_Panama } procedure THash_Panama.DoInit; begin FillChar(FLFSRBuffer, SizeOf(FLFSRBuffer), 0); FillChar(FDigest, SizeOf(FDigest), 0); FTap := 0; end; {$IFNDEF THash_Panama_asm} procedure THash_Panama.DoTransform(Buffer: PUInt32Array); var T0, T1, T2, T3: UInt32; PBufB, PTap0, PTap25: PUInt32Array; begin // perform non-linearity stage (GAMMA) T0 := FDigest[ 0]; T1 := FDigest[ 1]; FDigest[ 0] := FDigest[ 0] xor (FDigest[ 1] or not FDigest[ 2]); FDigest[ 1] := FDigest[ 1] xor (FDigest[ 2] or not FDigest[ 3]); FDigest[ 2] := FDigest[ 2] xor (FDigest[ 3] or not FDigest[ 4]); FDigest[ 3] := FDigest[ 3] xor (FDigest[ 4] or not FDigest[ 5]); FDigest[ 4] := FDigest[ 4] xor (FDigest[ 5] or not FDigest[ 6]); FDigest[ 5] := FDigest[ 5] xor (FDigest[ 6] or not FDigest[ 7]); FDigest[ 6] := FDigest[ 6] xor (FDigest[ 7] or not FDigest[ 8]); FDigest[ 7] := FDigest[ 7] xor (FDigest[ 8] or not FDigest[ 9]); FDigest[ 8] := FDigest[ 8] xor (FDigest[ 9] or not FDigest[10]); FDigest[ 9] := FDigest[ 9] xor (FDigest[10] or not FDigest[11]); FDigest[10] := FDigest[10] xor (FDigest[11] or not FDigest[12]); FDigest[11] := FDigest[11] xor (FDigest[12] or not FDigest[13]); FDigest[12] := FDigest[12] xor (FDigest[13] or not FDigest[14]); FDigest[13] := FDigest[13] xor (FDigest[14] or not FDigest[15]); FDigest[14] := FDigest[14] xor (FDigest[15] or not FDigest[16]); FDigest[15] := FDigest[15] xor (FDigest[16] or not T0); FDigest[16] := FDigest[16] xor (T0 or not T1); // perform bit-dispersion stage (PI) T0 := FDigest[ 1]; T1 := FDigest[ 7]; FDigest[ 1] := (T1 shl 1) or (T1 shr 31); T1 := FDigest[ 5]; FDigest[ 5] := (T0 shl 15) or (T0 shr 17); T0 := FDigest[ 8]; FDigest[ 8] := (T1 shl 4) or (T1 shr 28); T1 := FDigest[ 6]; FDigest[ 6] := (T0 shl 21) or (T0 shr 11); T0 := FDigest[13]; FDigest[13] := (T1 shl 27) or (T1 shr 5); T1 := FDigest[14]; FDigest[14] := (T0 shl 9) or (T0 shr 23); T0 := FDigest[ 2]; FDigest[ 2] := (T1 shl 3) or (T1 shr 29); T1 := FDigest[10]; FDigest[10] := (T0 shl 23) or (T0 shr 9); T0 := FDigest[16]; FDigest[16] := (T1 shl 8) or (T1 shr 24); T1 := FDigest[12]; FDigest[12] := (T0 shl 14) or (T0 shr 18); T0 := FDigest[ 9]; FDigest[ 9] := (T1 shl 13) or (T1 shr 19); T1 := FDigest[11]; FDigest[11] := (T0 shl 2) or (T0 shr 30); T0 := FDigest[ 4]; FDigest[ 4] := (T1 shl 10) or (T1 shr 22); T1 := FDigest[ 3]; FDigest[ 3] := (T0 shl 6) or (T0 shr 26); T0 := FDigest[15]; FDigest[15] := (T1 shl 24) or (T1 shr 8); FDigest[ 7] := (T0 shl 28) or (T0 shr 4); // LFSR emulation PBufB := @FLFSRBuffer[(FTap + 16) and 31]; FTap := (FTap - 1) and 31; PTap0 := @FLFSRBuffer[FTap]; PTap25 := @FLFSRBuffer[(FTap + 25) and 31]; // update the LFSR buffer (LAMBDA_PUSH) PTap25[ 0] := PTap25[ 0] xor PTap0[ 2]; PTap25[ 1] := PTap25[ 1] xor PTap0[ 3]; PTap25[ 2] := PTap25[ 2] xor PTap0[ 4]; PTap25[ 3] := PTap25[ 3] xor PTap0[ 5]; PTap25[ 4] := PTap25[ 4] xor PTap0[ 6]; PTap25[ 5] := PTap25[ 5] xor PTap0[ 7]; PTap25[ 6] := PTap25[ 6] xor PTap0[ 0]; PTap25[ 7] := PTap25[ 7] xor PTap0[ 1]; PTap0[ 0] := PTap0[ 0] xor Buffer[ 0]; PTap0[ 1] := PTap0[ 1] xor Buffer[ 1]; PTap0[ 2] := PTap0[ 2] xor Buffer[ 2]; PTap0[ 3] := PTap0[ 3] xor Buffer[ 3]; PTap0[ 4] := PTap0[ 4] xor Buffer[ 4]; PTap0[ 5] := PTap0[ 5] xor Buffer[ 5]; PTap0[ 6] := PTap0[ 6] xor Buffer[ 6]; PTap0[ 7] := PTap0[ 7] xor Buffer[ 7]; // perform diffusion stage (THETA) + buffer injection stage (SIGMA) T0 := FDigest[ 0]; T1 := FDigest[ 1]; T2 := FDigest[ 2]; T3 := FDigest[ 3]; FDigest[ 0] := FDigest[ 0] xor FDigest[ 1] xor FDigest[ 4] xor 1; FDigest[ 1] := FDigest[ 1] xor FDigest[ 2] xor FDigest[ 5] xor Buffer[ 0]; FDigest[ 2] := FDigest[ 2] xor FDigest[ 3] xor FDigest[ 6] xor Buffer[ 1]; FDigest[ 3] := FDigest[ 3] xor FDigest[ 4] xor FDigest[ 7] xor Buffer[ 2]; FDigest[ 4] := FDigest[ 4] xor FDigest[ 5] xor FDigest[ 8] xor Buffer[ 3]; FDigest[ 5] := FDigest[ 5] xor FDigest[ 6] xor FDigest[ 9] xor Buffer[ 4]; FDigest[ 6] := FDigest[ 6] xor FDigest[ 7] xor FDigest[10] xor Buffer[ 5]; FDigest[ 7] := FDigest[ 7] xor FDigest[ 8] xor FDigest[11] xor Buffer[ 6]; FDigest[ 8] := FDigest[ 8] xor FDigest[ 9] xor FDigest[12] xor Buffer[ 7]; FDigest[ 9] := FDigest[ 9] xor FDigest[10] xor FDigest[13] xor PBufB[ 0]; FDigest[10] := FDigest[10] xor FDigest[11] xor FDigest[14] xor PBufB[ 1]; FDigest[11] := FDigest[11] xor FDigest[12] xor FDigest[15] xor PBufB[ 2]; FDigest[12] := FDigest[12] xor FDigest[13] xor FDigest[16] xor PBufB[ 3]; FDigest[13] := FDigest[13] xor FDigest[14] xor T0 xor PBufB[ 4]; FDigest[14] := FDigest[14] xor FDigest[15] xor T1 xor PBufB[ 5]; FDigest[15] := FDigest[15] xor FDigest[16] xor T2 xor PBufB[ 6]; FDigest[16] := FDigest[16] xor T0 xor T3 xor PBufB[ 7]; end; {$ENDIF !THash_Panama_asm} procedure THash_Panama.DoDone; begin if FPaddingByte = 0 then FPaddingByte := $01; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); DoPull; FillChar(FLFSRBuffer, SizeOf(FLFSRBuffer), 0); FTap := 0; end; {$IFNDEF THash_Panama_asm} procedure THash_Panama.DoPull; var PBufL, PBufB, PTap0, PTap25: PUInt32Array; T0, T1, T2, T3: UInt32; I: Integer; begin for I := 0 to 31 do begin // LFSR emulation PBufL := @FLFSRBuffer[(FTap + 4) and 31]; PBufB := @FLFSRBuffer[(FTap + 16) and 31]; FTap := (FTap - 1) and 31; PTap0 := @FLFSRBuffer[FTap]; PTap25 := @FLFSRBuffer[(FTap + 25) and 31]; // update the LFSR buffer (LAMBDA_PULL) PTap25[ 0] := PTap25[ 0] xor PTap0[ 2]; PTap25[ 1] := PTap25[ 1] xor PTap0[ 3]; PTap25[ 2] := PTap25[ 2] xor PTap0[ 4]; PTap25[ 3] := PTap25[ 3] xor PTap0[ 5]; PTap25[ 4] := PTap25[ 4] xor PTap0[ 6]; PTap25[ 5] := PTap25[ 5] xor PTap0[ 7]; PTap25[ 6] := PTap25[ 6] xor PTap0[ 0]; PTap25[ 7] := PTap25[ 7] xor PTap0[ 1]; PTap0[ 0] := PTap0[ 0] xor FDigest[ 1]; PTap0[ 1] := PTap0[ 1] xor FDigest[ 2]; PTap0[ 2] := PTap0[ 2] xor FDigest[ 3]; PTap0[ 3] := PTap0[ 3] xor FDigest[ 4]; PTap0[ 4] := PTap0[ 4] xor FDigest[ 5]; PTap0[ 5] := PTap0[ 5] xor FDigest[ 6]; PTap0[ 6] := PTap0[ 6] xor FDigest[ 7]; PTap0[ 7] := PTap0[ 7] xor FDigest[ 8]; // perform non-linearity stage (GAMMA) T0 := FDigest[ 0]; T1 := FDigest[ 1]; FDigest[ 0] := FDigest[ 0] xor (FDigest[ 1] or not FDigest[ 2]); FDigest[ 1] := FDigest[ 1] xor (FDigest[ 2] or not FDigest[ 3]); FDigest[ 2] := FDigest[ 2] xor (FDigest[ 3] or not FDigest[ 4]); FDigest[ 3] := FDigest[ 3] xor (FDigest[ 4] or not FDigest[ 5]); FDigest[ 4] := FDigest[ 4] xor (FDigest[ 5] or not FDigest[ 6]); FDigest[ 5] := FDigest[ 5] xor (FDigest[ 6] or not FDigest[ 7]); FDigest[ 6] := FDigest[ 6] xor (FDigest[ 7] or not FDigest[ 8]); FDigest[ 7] := FDigest[ 7] xor (FDigest[ 8] or not FDigest[ 9]); FDigest[ 8] := FDigest[ 8] xor (FDigest[ 9] or not FDigest[10]); FDigest[ 9] := FDigest[ 9] xor (FDigest[10] or not FDigest[11]); FDigest[10] := FDigest[10] xor (FDigest[11] or not FDigest[12]); FDigest[11] := FDigest[11] xor (FDigest[12] or not FDigest[13]); FDigest[12] := FDigest[12] xor (FDigest[13] or not FDigest[14]); FDigest[13] := FDigest[13] xor (FDigest[14] or not FDigest[15]); FDigest[14] := FDigest[14] xor (FDigest[15] or not FDigest[16]); FDigest[15] := FDigest[15] xor (FDigest[16] or not T0); FDigest[16] := FDigest[16] xor (T0 or not T1); // perform bit-dispersion stage (PI) T0 := FDigest[ 1]; T1 := FDigest[ 7]; FDigest[ 1] := (T1 shl 1) or (T1 shr 31); T1 := FDigest[ 5]; FDigest[ 5] := (T0 shl 15) or (T0 shr 17); T0 := FDigest[ 8]; FDigest[ 8] := (T1 shl 4) or (T1 shr 28); T1 := FDigest[ 6]; FDigest[ 6] := (T0 shl 21) or (T0 shr 11); T0 := FDigest[13]; FDigest[13] := (T1 shl 27) or (T1 shr 5); T1 := FDigest[14]; FDigest[14] := (T0 shl 9) or (T0 shr 23); T0 := FDigest[ 2]; FDigest[ 2] := (T1 shl 3) or (T1 shr 29); T1 := FDigest[10]; FDigest[10] := (T0 shl 23) or (T0 shr 9); T0 := FDigest[16]; FDigest[16] := (T1 shl 8) or (T1 shr 24); T1 := FDigest[12]; FDigest[12] := (T0 shl 14) or (T0 shr 18); T0 := FDigest[ 9]; FDigest[ 9] := (T1 shl 13) or (T1 shr 19); T1 := FDigest[11]; FDigest[11] := (T0 shl 2) or (T0 shr 30); T0 := FDigest[ 4]; FDigest[ 4] := (T1 shl 10) or (T1 shr 22); T1 := FDigest[ 3]; FDigest[ 3] := (T0 shl 6) or (T0 shr 26); T0 := FDigest[15]; FDigest[15] := (T1 shl 24) or (T1 shr 8); FDigest[ 7] := (T0 shl 28) or (T0 shr 4); // perform diffusion stage (THETA) + buffer injection stage (SIGMA) T0 := FDigest[ 0]; T1 := FDigest[ 1]; T2 := FDigest[ 2]; T3 := FDigest[ 3]; FDigest[ 0] := FDigest[ 0] xor FDigest[ 1] xor FDigest[ 4] xor 1; FDigest[ 1] := FDigest[ 1] xor FDigest[ 2] xor FDigest[ 5] xor PBufL[ 0]; FDigest[ 2] := FDigest[ 2] xor FDigest[ 3] xor FDigest[ 6] xor PBufL[ 1]; FDigest[ 3] := FDigest[ 3] xor FDigest[ 4] xor FDigest[ 7] xor PBufL[ 2]; FDigest[ 4] := FDigest[ 4] xor FDigest[ 5] xor FDigest[ 8] xor PBufL[ 3]; FDigest[ 5] := FDigest[ 5] xor FDigest[ 6] xor FDigest[ 9] xor PBufL[ 4]; FDigest[ 6] := FDigest[ 6] xor FDigest[ 7] xor FDigest[10] xor PBufL[ 5]; FDigest[ 7] := FDigest[ 7] xor FDigest[ 8] xor FDigest[11] xor PBufL[ 6]; FDigest[ 8] := FDigest[ 8] xor FDigest[ 9] xor FDigest[12] xor PBufL[ 7]; FDigest[ 9] := FDigest[ 9] xor FDigest[10] xor FDigest[13] xor PBufB[ 0]; FDigest[10] := FDigest[10] xor FDigest[11] xor FDigest[14] xor PBufB[ 1]; FDigest[11] := FDigest[11] xor FDigest[12] xor FDigest[15] xor PBufB[ 2]; FDigest[12] := FDigest[12] xor FDigest[13] xor FDigest[16] xor PBufB[ 3]; FDigest[13] := FDigest[13] xor FDigest[14] xor T0 xor PBufB[ 4]; FDigest[14] := FDigest[14] xor FDigest[15] xor T1 xor PBufB[ 5]; FDigest[15] := FDigest[15] xor FDigest[16] xor T2 xor PBufB[ 6]; FDigest[16] := FDigest[16] xor T0 xor T3 xor PBufB[ 7]; end; // move state to Digest buffer FDigest[0] := FDigest[ 9]; FDigest[1] := FDigest[10]; FDigest[2] := FDigest[11]; FDigest[3] := FDigest[12]; FDigest[4] := FDigest[13]; FDigest[5] := FDigest[14]; FDigest[6] := FDigest[15]; FDigest[7] := FDigest[16]; end; {$ENDIF !THash_Panama_asm} function THash_Panama.Digest: PByteArray; begin Result := @FDigest; end; class function THash_Panama.DigestSize: UInt32; begin Result := 32; end; class function THash_Panama.BlockSize: UInt32; begin Result := 32 end; { THashBaseWhirlpool } {$IFNDEF THashBaseWhirlpool_asm} procedure THashBaseWhirlpool.DoTransform(Buffer: PUInt32Array); type PWhirlData = ^TWhirlData; TWhirlData = array[0..15] of UInt32; PWhirlTable = ^TWhirlTable; TWhirlTable = array[0..7, 0..511] of UInt32; procedure Whirl(var L: TWhirlData; const K: TWhirlData; const T: PWhirlTable); begin L[0*2+0] := T[0, ((K[ 0] shl 1) and $1fe)] xor T[1, ((K[14] shr 7) and $1fe)] xor T[2, ((K[12] shr 15) and $1fe)] xor T[3, ((K[10] shr 23) and $1fe)] xor T[4, ((K[ 9] shl 1) and $1fe)] xor T[5, ((K[ 7] shr 7) and $1fe)] xor T[6, ((K[ 5] shr 15) and $1fe)] xor T[7, ((K[ 3] shr 23) and $1fe)]; L[0*2+1] := T[0, ((K[ 0] shl 1) and $1fe)+1] xor T[1, ((K[14] shr 7) and $1fe)+1] xor T[2, ((K[12] shr 15) and $1fe)+1] xor T[3, ((K[10] shr 23) and $1fe)+1] xor T[4, ((K[ 9] shl 1) and $1fe)+1] xor T[5, ((K[ 7] shr 7) and $1fe)+1] xor T[6, ((K[ 5] shr 15) and $1fe)+1] xor T[7, ((K[ 3] shr 23) and $1fe)+1]; L[1*2+0] := T[0, ((K[ 2] shl 1) and $1fe)] xor T[1, ((K[ 0] shr 7) and $1fe)] xor T[2, ((K[14] shr 15) and $1fe)] xor T[3, ((K[12] shr 23) and $1fe)] xor T[4, ((K[11] shl 1) and $1fe)] xor T[5, ((K[ 9] shr 7) and $1fe)] xor T[6, ((K[ 7] shr 15) and $1fe)] xor T[7, ((K[ 5] shr 23) and $1fe)]; L[1*2+1] := T[0, ((K[ 2] shl 1) and $1fe)+1] xor T[1, ((K[ 0] shr 7) and $1fe)+1] xor T[2, ((K[14] shr 15) and $1fe)+1] xor T[3, ((K[12] shr 23) and $1fe)+1] xor T[4, ((K[11] shl 1) and $1fe)+1] xor T[5, ((K[ 9] shr 7) and $1fe)+1] xor T[6, ((K[ 7] shr 15) and $1fe)+1] xor T[7, ((K[ 5] shr 23) and $1fe)+1]; L[2*2+0] := T[0, ((K[ 4] shl 1) and $1fe)] xor T[1, ((K[ 2] shr 7) and $1fe)] xor T[2, ((K[ 0] shr 15) and $1fe)] xor T[3, ((K[14] shr 23) and $1fe)] xor T[4, ((K[13] shl 1) and $1fe)] xor T[5, ((K[11] shr 7) and $1fe)] xor T[6, ((K[ 9] shr 15) and $1fe)] xor T[7, ((K[ 7] shr 23) and $1fe)]; L[2*2+1] := T[0, ((K[ 4] shl 1) and $1fe)+1] xor T[1, ((K[ 2] shr 7) and $1fe)+1] xor T[2, ((K[ 0] shr 15) and $1fe)+1] xor T[3, ((K[14] shr 23) and $1fe)+1] xor T[4, ((K[13] shl 1) and $1fe)+1] xor T[5, ((K[11] shr 7) and $1fe)+1] xor T[6, ((K[ 9] shr 15) and $1fe)+1] xor T[7, ((K[ 7] shr 23) and $1fe)+1]; L[3*2+0] := T[0, ((K[ 6] shl 1) and $1fe)] xor T[1, ((K[ 4] shr 7) and $1fe)] xor T[2, ((K[ 2] shr 15) and $1fe)] xor T[3, ((K[ 0] shr 23) and $1fe)] xor T[4, ((K[15] shl 1) and $1fe)] xor T[5, ((K[13] shr 7) and $1fe)] xor T[6, ((K[11] shr 15) and $1fe)] xor T[7, ((K[ 9] shr 23) and $1fe)]; L[3*2+1] := T[0, ((K[ 6] shl 1) and $1fe)+1] xor T[1, ((K[ 4] shr 7) and $1fe)+1] xor T[2, ((K[ 2] shr 15) and $1fe)+1] xor T[3, ((K[ 0] shr 23) and $1fe)+1] xor T[4, ((K[15] shl 1) and $1fe)+1] xor T[5, ((K[13] shr 7) and $1fe)+1] xor T[6, ((K[11] shr 15) and $1fe)+1] xor T[7, ((K[ 9] shr 23) and $1fe)+1]; L[4*2+0] := T[0, ((K[ 8] shl 1) and $1fe)] xor T[1, ((K[ 6] shr 7) and $1fe)] xor T[2, ((K[ 4] shr 15) and $1fe)] xor T[3, ((K[ 2] shr 23) and $1fe)] xor T[4, ((K[ 1] shl 1) and $1fe)] xor T[5, ((K[15] shr 7) and $1fe)] xor T[6, ((K[13] shr 15) and $1fe)] xor T[7, ((K[11] shr 23) and $1fe)]; L[4*2+1] := T[0, ((K[ 8] shl 1) and $1fe)+1] xor T[1, ((K[ 6] shr 7) and $1fe)+1] xor T[2, ((K[ 4] shr 15) and $1fe)+1] xor T[3, ((K[ 2] shr 23) and $1fe)+1] xor T[4, ((K[ 1] shl 1) and $1fe)+1] xor T[5, ((K[15] shr 7) and $1fe)+1] xor T[6, ((K[13] shr 15) and $1fe)+1] xor T[7, ((K[11] shr 23) and $1fe)+1]; L[5*2+0] := T[0, ((K[10] shl 1) and $1fe)] xor T[1, ((K[ 8] shr 7) and $1fe)] xor T[2, ((K[ 6] shr 15) and $1fe)] xor T[3, ((K[ 4] shr 23) and $1fe)] xor T[4, ((K[ 3] shl 1) and $1fe)] xor T[5, ((K[ 1] shr 7) and $1fe)] xor T[6, ((K[15] shr 15) and $1fe)] xor T[7, ((K[13] shr 23) and $1fe)]; L[5*2+1] := T[0, ((K[10] shl 1) and $1fe)+1] xor T[1, ((K[ 8] shr 7) and $1fe)+1] xor T[2, ((K[ 6] shr 15) and $1fe)+1] xor T[3, ((K[ 4] shr 23) and $1fe)+1] xor T[4, ((K[ 3] shl 1) and $1fe)+1] xor T[5, ((K[ 1] shr 7) and $1fe)+1] xor T[6, ((K[15] shr 15) and $1fe)+1] xor T[7, ((K[13] shr 23) and $1fe)+1]; L[6*2+0] := T[0, ((K[12] shl 1) and $1fe)] xor T[1, ((K[10] shr 7) and $1fe)] xor T[2, ((K[ 8] shr 15) and $1fe)] xor T[3, ((K[ 6] shr 23) and $1fe)] xor T[4, ((K[ 5] shl 1) and $1fe)] xor T[5, ((K[ 3] shr 7) and $1fe)] xor T[6, ((K[ 1] shr 15) and $1fe)] xor T[7, ((K[15] shr 23) and $1fe)]; L[6*2+1] := T[0, ((K[12] shl 1) and $1fe)+1] xor T[1, ((K[10] shr 7) and $1fe)+1] xor T[2, ((K[ 8] shr 15) and $1fe)+1] xor T[3, ((K[ 6] shr 23) and $1fe)+1] xor T[4, ((K[ 5] shl 1) and $1fe)+1] xor T[5, ((K[ 3] shr 7) and $1fe)+1] xor T[6, ((K[ 1] shr 15) and $1fe)+1] xor T[7, ((K[15] shr 23) and $1fe)+1]; L[7*2+0] := T[0, ((K[14] shl 1) and $1fe)] xor T[1, ((K[12] shr 7) and $1fe)] xor T[2, ((K[10] shr 15) and $1fe)] xor T[3, ((K[ 8] shr 23) and $1fe)] xor T[4, ((K[ 7] shl 1) and $1fe)] xor T[5, ((K[ 5] shr 7) and $1fe)] xor T[6, ((K[ 3] shr 15) and $1fe)] xor T[7, ((K[ 1] shr 23) and $1fe)]; L[7*2+1] := T[0, ((K[14] shl 1) and $1fe)+1] xor T[1, ((K[12] shr 7) and $1fe)+1] xor T[2, ((K[10] shr 15) and $1fe)+1] xor T[3, ((K[ 8] shr 23) and $1fe)+1] xor T[4, ((K[ 7] shl 1) and $1fe)+1] xor T[5, ((K[ 5] shr 7) and $1fe)+1] xor T[6, ((K[ 3] shr 15) and $1fe)+1] xor T[7, ((K[ 1] shr 23) and $1fe)+1]; end; var S, L, K: TWhirlData; I: Integer; begin Assert(not Odd(Whirlpool_Rounds)); Move(FDigest, K, SizeOf(FDigest)); XORBuffers(FDigest, Buffer[0], SizeOf(FDigest), S); // iterate over all rounds for I := 0 to Whirlpool_Rounds div 2 - 1 do begin Whirl(L, K, FTableC); L[0] := L[0] xor PUInt32Array(FTableR)[I*4+0]; L[1] := L[1] xor PUInt32Array(FTableR)[I*4+1]; Whirl(K, S, FTableC); XORBuffers(L, K, SizeOf(S), S); Whirl(K, L, FTableC); K[0] := K[0] xor PUInt32Array(FTableR)[I*4+2]; K[1] := K[1] xor PUInt32Array(FTableR)[I*4+3]; Whirl(L, S, FTableC); XORBuffers(K, L, SizeOf(S), S); end; XORBuffers(S, Buffer[0], SizeOf(FDigest), S); XORBuffers(S, FDigest, SizeOf(FDigest), FDigest); end; {$ENDIF !THashBaseWhirlpool_asm} procedure THashBaseWhirlpool.DoDone; var I: Integer; begin if FPaddingByte = 0 then FPaddingByte := $80; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); if FBufferIndex > FBufferSize - 32 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); for I := 31 downto 0 do FBuffer[63 - I] := PByteArray(@FCount)[I]; DoTransform(Pointer(FBuffer)); end; function THashBaseWhirlpool.Digest: PByteArray; begin Result := @FDigest; end; class function THashBaseWhirlpool.DigestSize: UInt32; begin Result := 64; end; class function THashBaseWhirlpool.BlockSize: UInt32; begin Result := 64; end; { THash_Whirlpool0 } procedure THash_Whirlpool0.DoInit; begin FillChar(FDigest, SizeOf(FDigest), 0); FTableC := @Whirlpool_C_U; FTableR := @Whirlpool_RC_U end; { THash_WhirlpoolT } procedure THash_WhirlpoolT.DoInit; begin FillChar(FDigest, SizeOf(FDigest), 0); FTableC := @Whirlpool_C_T; FTableR := @Whirlpool_RC_T; end; { THash_Whirlpool1_ } procedure THash_Whirlpool1_.DoInit; begin FillChar(FDigest, SizeOf(FDigest), 0); FTableC := @Whirlpool_C_1; FTableR := @Whirlpool_RC_1; end; { THash_Square } procedure THash_Square.DoInit; begin FillChar(FDigest, SizeOf(FDigest), 0); end; {$IFNDEF THash_Square_asm} procedure THash_Square.DoTransform(Buffer: PUInt32Array); var Key: array[0..8, 0..3] of UInt32; A, B, C, D: UInt32; AA, BB, CC, DD: UInt32; I: Integer; begin // Build and expand the Key, Digest include the Key Key[0, 0] := FDigest[0]; Key[0, 1] := FDigest[1]; Key[0, 2] := FDigest[2]; Key[0, 3] := FDigest[3]; for I := 1 to 8 do begin Key[I, 0] := Key[I - 1, 0] xor Key[I - 1, 3] shr 8 xor Key[I - 1, 3] shl 24 xor 1 shl (I - 1); Key[I, 1] := Key[I - 1, 1] xor Key[I, 0]; Key[I, 2] := Key[I - 1, 2] xor Key[I, 1]; Key[I, 3] := Key[I - 1, 3] xor Key[I, 2]; Key[I - 1, 0] := Square_PHIr[0, Key[I - 1, 0] and $FF] xor Square_PHIr[1, Key[I - 1, 0] shr 8 and $FF] xor Square_PHIr[2, Key[I - 1, 0] shr 16 and $FF] xor Square_PHIr[3, Key[I - 1, 0] shr 24 ]; Key[I - 1, 1] := Square_PHIr[0, Key[I - 1, 1] and $FF] xor Square_PHIr[1, Key[I - 1, 1] shr 8 and $FF] xor Square_PHIr[2, Key[I - 1, 1] shr 16 and $FF] xor Square_PHIr[3, Key[I - 1, 1] shr 24 ]; Key[I - 1, 2] := Square_PHIr[0, Key[I - 1, 2] and $FF] xor Square_PHIr[1, Key[I - 1, 2] shr 8 and $FF] xor Square_PHIr[2, Key[I - 1, 2] shr 16 and $FF] xor Square_PHIr[3, Key[I - 1, 2] shr 24 ]; Key[I - 1, 3] := Square_PHIr[0, Key[I - 1, 3] and $FF] xor Square_PHIr[1, Key[I - 1, 3] shr 8 and $FF] xor Square_PHIr[2, Key[I - 1, 3] shr 16 and $FF] xor Square_PHIr[3, Key[I - 1, 3] shr 24 ]; end; // Encrypt begin here, same TCipher_Square.Encode A := Buffer[0] xor Key[0, 0]; B := Buffer[1] xor Key[0, 1]; C := Buffer[2] xor Key[0, 2]; D := Buffer[3] xor Key[0, 3]; for I := 0 to 6 do begin AA := Square_TE[0, A and $FF] xor Square_TE[1, B and $FF] xor Square_TE[2, C and $FF] xor Square_TE[3, D and $FF] xor Key[I + 1, 0]; BB := Square_TE[0, A shr 8 and $FF] xor Square_TE[1, B shr 8 and $FF] xor Square_TE[2, C shr 8 and $FF] xor Square_TE[3, D shr 8 and $FF] xor Key[I + 1, 1]; CC := Square_TE[0, A shr 16 and $FF] xor Square_TE[1, B shr 16 and $FF] xor Square_TE[2, C shr 16 and $FF] xor Square_TE[3, D shr 16 and $FF] xor Key[I + 1, 2]; DD := Square_TE[0, A shr 24 ] xor Square_TE[1, B shr 24 ] xor Square_TE[2, C shr 24 ] xor Square_TE[3, D shr 24 ] xor Key[I + 1, 3]; A := AA; B := BB; C := CC; D := DD; end; FDigest[0] := Buffer[0] xor Square_SEint[A and $FF] xor Square_SEint[B and $FF] shl 8 xor Square_SEint[C and $FF] shl 16 xor Square_SEint[D and $FF] shl 24 xor Key[8, 0]; FDigest[1] := Buffer[1] xor Square_SEint[A shr 8 and $FF] xor Square_SEint[B shr 8 and $FF] shl 8 xor Square_SEint[C shr 8 and $FF] shl 16 xor Square_SEint[D shr 8 and $FF] shl 24 xor Key[8, 1]; FDigest[2] := Buffer[2] xor Square_SEint[A shr 16 and $FF] xor Square_SEint[B shr 16 and $FF] shl 8 xor Square_SEint[C shr 16 and $FF] shl 16 xor Square_SEint[D shr 16 and $FF] shl 24 xor Key[8, 2]; FDigest[3] := Buffer[3] xor Square_SEint[A shr 24 ] xor Square_SEint[B shr 24 ] shl 8 xor Square_SEint[C shr 24 ] shl 16 xor Square_SEint[D shr 24 ] shl 24 xor Key[8, 3]; end; {$ENDIF !THash_Square_asm} procedure THash_Square.DoDone; var I: Integer; begin if FPaddingByte = 0 then FPaddingByte := $80; FBuffer[FBufferIndex] := FPaddingByte; Inc(FBufferIndex); if FBufferIndex > FBufferSize - 8 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); for I := 7 downto 0 do FBuffer[15 - I] := PByteArray(@FCount[0])[I]; DoTransform(Pointer(FBuffer)); end; function THash_Square.Digest: PByteArray; begin Result := @FDigest; end; class function THash_Square.DigestSize: UInt32; begin Result := 16; end; class function THash_Square.BlockSize: UInt32; begin Result := 16; end; { THashBaseSnefru } procedure THashBaseSnefru.SetRounds(Value: Integer); begin if (Value < 2) or (Value > 8) then Value := 8; FRounds := Value; end; procedure THashBaseSnefru.DoInit; begin FillChar(FDigest, SizeOf(FDigest), 0); SetRounds(FRounds); end; class function THashBaseSnefru.GetMaxRounds: UInt8; begin Result := 8; end; class function THashBaseSnefru.GetMinRounds: UInt8; begin Result := 2; end; procedure THashBaseSnefru.DoDone; begin if FBufferIndex > 0 then begin FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); DoTransform(Pointer(FBuffer)); FBufferIndex := 0; end; FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0); PUInt32(@FBuffer[FBufferSize - 8])^ := SwapUInt32(FCount[1]); PUInt32(@FBuffer[FBufferSize - 4])^ := SwapUInt32(FCount[0]); DoTransform(Pointer(FBuffer)); SwapUInt32Buffer(FDigest, FDigest, 8); end; function THashBaseSnefru.Digest: PByteArray; begin Result := @FDigest; end; { THash_Snefru128 } {$IFNDEF THash_Snefru128_asm} procedure THash_Snefru128.DoTransform(Buffer: PUInt32Array); const ShiftTable: array[0..3] of Integer = (16, 8, 16, 24); var I, Index, ByteInWord, T, N, S, S0, S1: UInt32; D, Box0, Box1: PUInt32Array; begin D := @FDigest; SwapUInt32Buffer(Buffer[0], D[4], 12); Move(D[0], D[16], 16); Box0 := @Snefru_Data[0]; Box1 := @Snefru_Data[1]; for Index := 0 to FRounds - 1 do begin for ByteInWord := 0 to 3 do begin I := 0; N := D[0]; while I < 16 do begin S0 := Box0[N and $FF]; T := (I + 1) and 15; N := D[T] xor S0; D[T] := N; T := (I + 15) and 15; D[T] := D[T] xor S0; S1 := Box0[N and $FF]; T := (I + 2) and 15; N := D[T] xor S1; D[T] := N; T := (I + 16) and 15; D[T] := D[T] xor S1; S0 := Box1[N and $FF]; T := (I + 3) and 15; N := D[T] xor S0; D[T] := N; T := (I + 17) and 15; D[T] := D[T] xor S0; S1 := Box1[N and $FF]; T := (I + 4) and 15; N := D[T] xor S1; D[T] := N; T := (I + 18) and 15; D[T] := D[T] xor S1; Inc(I, 4); end; T := ShiftTable[ByteInWord]; S := 32 - T; for I := 0 to 15 do D[I] := D[I] shr T or D[I] shl S; end; Box0 := @Box0[512]; Box1 := @Box1[512]; end; for I := 0 to 3 do D[I] := D[I + 16] xor D[15 - I]; end; {$ENDIF !THash_Snefru128_asm} class function THash_Snefru128.DigestSize: UInt32; begin Result := 16; end; class function THash_Snefru128.BlockSize: UInt32; begin Result := 48 end; { THash_Snefru256 } {$IFNDEF THash_Snefru256_asm} procedure THash_Snefru256.DoTransform(Buffer: PUInt32Array); const ShiftTable: array[0..3] of Integer = (16, 8, 16, 24); var I, Index, ByteInWord, T, N, S, S0, S1: UInt32; D, Box0, Box1: PUInt32Array; begin D := @FDigest; SwapUInt32Buffer(Buffer[0], D[8], 8); Move(D[0], D[16], 32); Box0 := @Snefru_Data[0]; Box1 := @Snefru_Data[1]; for Index := 0 to FRounds - 1 do begin for ByteInWord := 0 to 3 do begin I := 0; N := D[0]; while I < 16 do begin S0 := Box0[N and $FF]; T := (I + 1) and 15; N := D[T] xor S0; D[T] := N; T := (I + 15) and 15; D[T] := D[T] xor S0; S1 := Box0[N and $FF]; T := (I + 2) and 15; N := D[T] xor S1; D[T] := N; T := (I + 16) and 15; D[T] := D[T] xor S1; S0 := Box1[N and $FF]; T := (I + 3) and 15; N := D[T] xor S0; D[T] := N; T := (I + 17) and 15; D[T] := D[T] xor S0; S1 := Box1[N and $FF]; T := (I + 4) and 15; N := D[T] xor S1; D[T] := N; T := (I + 18) and 15; D[T] := D[T] xor S1; Inc(I, 4); end; T := ShiftTable[ByteInWord]; S := 32 - T; for I := 0 to 15 do D[I] := D[I] shr T or D[I] shl S; end; Box0 := @Box0[512]; Box1 := @Box1[512]; end; for I := 0 to 7 do D[I] := D[I + 16] xor D[15 - I]; end; {$ENDIF !THash_Snefru256_asm} class function THash_Snefru256.DigestSize: UInt32; begin Result := 32; end; class function THash_Snefru256.BlockSize: UInt32; begin Result := 32 end; { THash_Sapphire } procedure THash_Sapphire.DoInit; var I: Integer; begin FillChar(FDigest, SizeOf(FDigest), 0); FRotor := 1; FRatchet := 3; FAvalanche := 5; FPlain := 7; FCipher := 11; for I := 0 to 255 do FCards[I] := 255 - I; end; procedure THash_Sapphire.DoTransform(Buffer: PUInt32Array); begin // Empty on purpose: the base class for the hashes declares an abstract // DoTransform method and not providing an override for it would cause a // compiler warning end; procedure THash_Sapphire.SetDigestSize(Value: UInt8); begin if (Value >= 1) and (Value <= 64) then FDigestSize := Value else FDigestSize := DigestSize; end; procedure THash_Sapphire.DoDone; var I: Integer; begin for I := 255 downto 0 do Calc(I, 1); for I := 0 to DigestSize - 1 do begin Calc(#0#0, 1); PByteArray(@FDigest)[I] := FCipher; end; end; {$IFNDEF THash_Sapphire_asm} procedure THash_Sapphire.Calc(const Data; DataSize: Integer); var Cipher, Ratchet, Rotor, Plain, Avalanche, T: UInt32; D: PByte; begin D := @Data; Cipher := FCipher; Ratchet := FRatchet; Rotor := FRotor; Plain := FPlain; Avalanche := FAvalanche; while DataSize > 0 do begin Dec(DataSize); Ratchet := (Ratchet + FCards[Rotor]) and $FF; Rotor := (Rotor + 1) and $FF; T := FCards[Cipher]; FCards[Cipher] := FCards[Ratchet]; FCards[Ratchet] := FCards[Plain]; FCards[Plain] := FCards[Rotor]; FCards[Rotor] := T; Avalanche := (Avalanche + FCards[T]) and $FF; T := (FCards[Plain] + FCards[Cipher] + FCards[Avalanche]) and $FF; Plain := D^; Inc(D); Cipher := Plain xor FCards[FCards[T]] xor FCards[(FCards[Ratchet] + FCards[Rotor]) and $FF]; end; FCipher := Cipher; FRatchet := Ratchet; FRotor := Rotor; FPlain := Plain; FAvalanche := Avalanche; end; {$ENDIF !THash_Sapphire_asm} function THash_Sapphire.Digest: PByteArray; begin Result := @FDigest; end; function THash_Sapphire.DigestAsBytes: TBytes; var Size: Integer; begin if FDigestSize > 0 then Size := FDigestSize else Size := DigestSize; SetLength(Result, Size); if Size <> 0 then Move(FDigest, Result[0], Size); end; class function THash_Sapphire.DigestSize: UInt32; begin Result := 64; end; class function THash_Sapphire.BlockSize: UInt32; begin Result := 1; end; {$IFDEF RESTORE_RANGECHECKS}{$R+}{$ENDIF} {$IFDEF RESTORE_OVERFLOWCHECKS}{$Q+}{$ENDIF} { THash_SHA3_224 } class function THash_SHA3_224.BlockSize: UInt32; begin Result := 144; end; class function THash_SHA3_224.DigestSize: UInt32; begin Result := 28; end; procedure THash_SHA3_224.DoInit; begin inherited; InitSponge(1152, 448); FSpongeState.FixedOutputLength := 224; end; { THash_SHA3_256 } class function THash_SHA3_256.BlockSize: UInt32; begin Result := 136; end; class function THash_SHA3_256.DigestSize: UInt32; begin Result := 32; end; procedure THash_SHA3_256.DoInit; begin inherited; InitSponge(1088, 512); FSpongeState.fixedOutputLength := 256; end; { THash_SHA3_384 } class function THash_SHA3_384.BlockSize: UInt32; begin Result := 104; end; class function THash_SHA3_384.DigestSize: UInt32; begin Result := 48; end; procedure THash_SHA3_384.DoInit; begin inherited; InitSponge(832, 768); FSpongeState.fixedOutputLength := 384; end; { THash_SHA3_512 } class function THash_SHA3_512.BlockSize: UInt32; begin Result := 72; end; class function THash_SHA3_512.DigestSize: UInt32; begin Result := 64; end; procedure THash_SHA3_512.DoInit; begin inherited; InitSponge(576, 1024); FSpongeState.fixedOutputLength := 512; end; { THash_SHA3Base } procedure THash_SHA3Base.InitSponge(Rate, Capacity: UInt16); begin // This is the only place where state.error is reset to 0 = SUCCESS FillChar(FSpongeState, SizeOf(FSpongeState), 0); if (Rate + Capacity <> 1600) or (Rate = 0) or (Rate >= 1600) or ((Rate and 63) <> 0) then raise EDECHashException.CreateFmt(sHashInitFailure, ['SHA3', 'rate: ' + IntToStr(Rate) + ' capacity: ' + IntToStr(Capacity)]); FSpongeState.Rate := Rate; FSpongeState.Capacity := Capacity; end; procedure THash_SHA3Base.KeccakAbsorb(var state: TState_B; data: PUInt64; laneCount: Integer); begin XORIntoState(TState_L(state), data, laneCount); KeccakPermutation(TState_L(state)); end; {$IFDEF PUREPASCAL} function THash_SHA3Base.RotL(const x: UInt64; c: Integer): UInt64; begin Result := (x shl c) or (x shr (64-c)); end; function THash_SHA3Base.RotL1(var x: UInt64): UInt64; begin Result := (x shl 1) or (x shr (64-1)); end; procedure THash_SHA3Base.KeccakPermutation(var state: TState_L); var A : PUInt64Array; B : array[0..24] of UInt64; C0, C1, C2, C3, C4, D0, D1, D2, D3, D4: UInt64; i : Integer; begin A := PUInt64Array(@state); for i := 0 to 23 do begin C0 := A[00] xor A[05] xor A[10] xor A[15] xor A[20]; C1 := A[01] xor A[06] xor A[11] xor A[16] xor A[21]; C2 := A[02] xor A[07] xor A[12] xor A[17] xor A[22]; C3 := A[03] xor A[08] xor A[13] xor A[18] xor A[23]; C4 := A[04] xor A[09] xor A[14] xor A[19] xor A[24]; D0 := RotL1(C0) xor C3; D1 := RotL1(C1) xor C4; D2 := RotL1(C2) xor C0; D3 := RotL1(C3) xor C1; D4 := RotL1(C4) xor C2; B[00] := A[00] xor D1; B[01] := RotL(A[06] xor D2, 44); B[02] := RotL(A[12] xor D3, 43); B[03] := RotL(A[18] xor D4, 21); B[04] := RotL(A[24] xor D0, 14); B[05] := RotL(A[03] xor D4, 28); B[06] := RotL(A[09] xor D0, 20); B[07] := RotL(A[10] xor D1, 3); B[08] := RotL(A[16] xor D2, 45); B[09] := RotL(A[22] xor D3, 61); B[10] := RotL(A[01] xor D2, 1); B[11] := RotL(A[07] xor D3, 6); B[12] := RotL(A[13] xor D4, 25); B[13] := RotL(A[19] xor D0, 8); B[14] := RotL(A[20] xor D1, 18); B[15] := RotL(A[04] xor D0, 27); B[16] := RotL(A[05] xor D1, 36); B[17] := RotL(A[11] xor D2, 10); B[18] := RotL(A[17] xor D3, 15); B[19] := RotL(A[23] xor D4, 56); B[20] := RotL(A[02] xor D3, 62); B[21] := RotL(A[08] xor D4, 55); B[22] := RotL(A[14] xor D0, 39); B[23] := RotL(A[15] xor D1, 41); B[24] := RotL(A[21] xor D2, 2); A[00] := B[00] xor ((not B[01]) and B[02]); A[01] := B[01] xor ((not B[02]) and B[03]); A[02] := B[02] xor ((not B[03]) and B[04]); A[03] := B[03] xor ((not B[04]) and B[00]); A[04] := B[04] xor ((not B[00]) and B[01]); A[05] := B[05] xor ((not B[06]) and B[07]); A[06] := B[06] xor ((not B[07]) and B[08]); A[07] := B[07] xor ((not B[08]) and B[09]); A[08] := B[08] xor ((not B[09]) and B[05]); A[09] := B[09] xor ((not B[05]) and B[06]); A[10] := B[10] xor ((not B[11]) and B[12]); A[11] := B[11] xor ((not B[12]) and B[13]); A[12] := B[12] xor ((not B[13]) and B[14]); A[13] := B[13] xor ((not B[14]) and B[10]); A[14] := B[14] xor ((not B[10]) and B[11]); A[15] := B[15] xor ((not B[16]) and B[17]); A[16] := B[16] xor ((not B[17]) and B[18]); A[17] := B[17] xor ((not B[18]) and B[19]); A[18] := B[18] xor ((not B[19]) and B[15]); A[19] := B[19] xor ((not B[15]) and B[16]); A[20] := B[20] xor ((not B[21]) and B[22]); A[21] := B[21] xor ((not B[22]) and B[23]); A[22] := B[22] xor ((not B[23]) and B[24]); A[23] := B[23] xor ((not B[24]) and B[20]); A[24] := B[24] xor ((not B[20]) and B[21]); A[00] := A[00] xor cRoundConstants[i]; end; end; {$ELSE} // Must be procedural as otherwise the parameters get passed in different // CPU registers and the complete ASM code would have needed to be rewritten. procedure KeccakPermutationKernel(B, A, C : Pointer); asm {$IFDEF X86ASM} {$INCLUDE DECHash.sha3_mmx.inc} {$ELSE} {$INCLUDE DECHash.sha3_x64.inc} {$ENDIF} end; procedure THash_SHA3Base.KeccakPermutation(var state: TState_L); var A : PUInt64Array; B : array [0..24] of UInt64; C : array [0..4] of UInt64; i : Integer; {$IFDEF X86ASM} procedure EMMS; asm // This operation marks the x87 FPU data registers (which are aliased to the // MMX technology registers) as available for use by x87 FPU floating-point // instructions. emms end; {$ENDIF} begin A := PUInt64Array(@state); for i:=0 to 23 do begin KeccakPermutationKernel(@B, A, @C); A[00] := A[00] xor cRoundConstants[i]; end; {$IFDEF X86ASM} EMMS; {$ENDIF} end; {$ENDIF} procedure THash_SHA3Base.PadAndSwitchToSqueezingPhase; var i: integer; begin // Note: the bits are numbered from 0 = LSB to 7 = MSB if (FSpongeState.BitsInQueue + 1 = FSpongeState.Rate) then begin i := FSpongeState.BitsInQueue div 8; FSpongeState.DataQueue[i] := FSpongeState.DataQueue[i] or (1 shl (FSpongeState.BitsInQueue and 7)); AbsorbQueue; FillChar(FSpongeState.DataQueue, FSpongeState.Rate div 8, 0); end else begin i := FSpongeState.BitsInQueue div 8; FillChar(FSpongeState.DataQueue[(FSpongeState.BitsInQueue+7) div 8], FSpongeState.Rate div 8 - (FSpongeState.BitsInQueue+7) div 8, 0); FSpongeState.DataQueue[i] := FSpongeState.DataQueue[i] or (1 shl (FSpongeState.BitsInQueue and 7)); end; i := (FSpongeState.Rate-1) div 8; FSpongeState.DataQueue[i] := FSpongeState.DataQueue[i] or (1 shl ((FSpongeState.Rate-1) and 7)); AbsorbQueue; ExtractFromState(@FSpongeState.DataQueue, TState_L(FSpongeState.State), FSpongeState.Rate div 64); FSpongeState.bitsAvailableForSqueezing := FSpongeState.Rate; FSpongeState.SqueezeActive := true; end; procedure THash_SHA3Base.Squeeze(var Output: TSHA3Digest; OutputLength: Int32); var i : Int32; PartialBlock : Int16; begin if not FSpongeState.SqueezeActive then PadAndSwitchToSqueezingPhase; // Only multiple of 8 bits are allowed, truncation must be done at user level if OutputLength and 7 <> 0 then raise EDECHashException.CreateFmt(aSHA3AbsorbFailure, [OutputLength, 'true']); i := 0; while i < OutputLength do begin if FSpongeState.bitsAvailableForSqueezing = 0 then begin KeccakPermutation(TState_L(FSpongeState.State)); ExtractFromState(@FSpongeState.DataQueue, TState_L(FSpongeState.State), FSpongeState.Rate div 64); FSpongeState.bitsAvailableForSqueezing := FSpongeState.Rate; end; PartialBlock := FSpongeState.bitsAvailableForSqueezing; if PartialBlock > OutputLength - i then PartialBlock := OutputLength - i; move(FSpongeState.DataQueue[(FSpongeState.Rate - FSpongeState.bitsAvailableForSqueezing) div 8], output[i div 8], PartialBlock div 8); dec(FSpongeState.bitsAvailableForSqueezing, PartialBlock); inc(i, PartialBlock); end; end; procedure THash_SHA3Base.XORIntoState(var state: TState_L; pI: PUInt64; laneCount: Integer); var pS: PUInt64; i: Integer; begin pS := @state[0]; for i:=laneCount-1 downto 0 do begin pS^ := pS^ xor pI^; Inc(pI); Inc(pS); end; end; procedure THash_SHA3Base.Absorb(Data: PBABytes; DatabitLen: Int32); var i, j, wholeBlocks, partialBlock: Integer; partialByte: Integer; curData: PUInt64; begin // if a number of bits which cannot be divided by 8 without reminder is in the // queue or algorithm is already in squeezing state if (FSpongeState.BitsInQueue and 7 <> 0) or FSpongeState.SqueezeActive then begin raise EDECHashException.CreateFmt(aSHA3AbsorbFailure, [FSpongeState.BitsInQueue, BoolToStr(FSpongeState.SqueezeActive, true)]); end; i := 0; while i < databitlen do begin if ((FSpongeState.BitsInQueue = 0) and (databitlen >= FSpongeState.Rate) and (i <= (databitlen - FSpongeState.Rate))) then begin wholeBlocks := (databitlen-i) div FSpongeState.Rate; curData := @data^[i div 8]; j := 0; while j < wholeBlocks do begin KeccakAbsorb(FSpongeState.State, curData, FSpongeState.Rate div 64); Inc(j); Inc(PByte(curData), FSpongeState.Rate div 8); end; Inc(i, wholeBlocks * FSpongeState.Rate); end else begin partialBlock := databitlen - i; if partialBlock + FSpongeState.BitsInQueue > FSpongeState.Rate then partialBlock := FSpongeState.Rate - FSpongeState.BitsInQueue; partialByte := partialBlock and 7; Dec(partialBlock, partialByte); Move(data^[i div 8], FSpongeState.DataQueue[FSpongeState.BitsInQueue div 8], partialBlock div 8); Inc(FSpongeState.BitsInQueue, partialBlock); Inc(i, partialBlock); if FSpongeState.BitsInQueue=FSpongeState.Rate then AbsorbQueue; if partialByte > 0 then begin FSpongeState.DataQueue[FSpongeState.BitsInQueue div 8] := data^[i div 8] and ((1 shl partialByte)-1); Inc(FSpongeState.BitsInQueue, partialByte); Inc(i, partialByte); end; end; end; end; procedure THash_SHA3Base.AbsorbQueue; begin // state.bitsInQueue is assumed to be equal to state.rat KeccakAbsorb(FSpongeState.State, @FSpongeState.DataQueue, FSpongeState.Rate div 64); FSpongeState.BitsInQueue := 0; end; procedure THash_SHA3Base.Calc(const Data; DataSize: Integer); var DataPtr : PBABytes; RoundSize : UInt32; const // Maximum number of bytes one can process in one round MaxRoundSize = MaxInt div 8; begin // due to the way the inherited calc is constructed it must not be called here! if (DataSize > 0) then begin DataPtr := PBABytes(@Data); while (UInt32(DataSize) > 0) do begin RoundSize := DataSize; if (RoundSize > MaxRoundSize) then RoundSize := MaxRoundSize; Absorb(DataPtr, RoundSize * 8); Dec(DataSize, RoundSize); Inc(DataPtr, RoundSize); end; end; end; function THash_SHA3Base.Digest: PByteArray; begin Result := @FDigest; end; procedure THash_SHA3Base.DoDone; begin FinalBit_LSB(FFinalByte, FFinalByteLength, FDigest); end; procedure THash_SHA3Base.DoInit; begin inherited; FillChar(FDIgest[0], Length(FDigest), 0); end; procedure THash_SHA3Base.DoUpdate(Data: Pointer; DataBitLen: Int32); var LastByte: Byte; begin // No partial byte if DataBitLen and 7 = 0 then Absorb(Data, DataBitLen) else begin // Data contains a partial byte. Calculate the whole bytes first then the // partial one. Absorb(Data, DataBitLen - (DataBitLen and 7)); // Align the last partial byte to the least significant bits LastByte := PBABytes(Data)^[DataBitLen div 8] shr (8 - (DataBitLen and 7)); Absorb(@LastByte, DataBitLen and 7); end; end; procedure THash_SHA3Base.ExtractFromState(outp: Pointer; const state: TState_L; laneCount: Integer); var pI, pS: PUInt64; i: Integer; begin pI := outp; pS := @state[0]; for i := laneCount - 1 downto 0 do begin pI^ := pS^; Inc(pI); Inc(pS); end; end; procedure THash_SHA3Base.FinalBit_LSB(Bits: Byte; Bitlen: UInt16; var Hashvalue: TSHA3Digest); var WorkingBitLen : Int16; lw : UInt16; begin // normalize Bitlen and Bits (zero high bits) Bitlen := Bitlen and 7; if Bitlen = 0 then lw := 0 else lw := Bits and pred(word(1) shl Bitlen); // 'append' (in LSB language) the domain separation bits if (FSpongeState.FixedOutputLength = 0) then begin lw := lw or (word($F) shl Bitlen); WorkingBitLen := Bitlen+4; end else begin // SHA3: append two bits 01 lw := lw or (word($2) shl Bitlen); WorkingBitLen := Bitlen+2; end; // update state with final bits if WorkingBitLen < 9 then begin // 0..8 bits, one call to update lw := lw shl (8-WorkingBitLen); DoUpdate(@lw, WorkingBitLen); // squeeze the digits from the sponge Squeeze(Hashvalue, FSpongeState.FixedOutputLength); end else begin // More than 8 bits, first a regular update with low byte DoUpdate(@lw, 8); // Finally update remaining last bits dec(WorkingBitLen,8); lw := lw shr WorkingBitLen; DoUpdate(@lw, WorkingBitLen); Squeeze(Hashvalue, FSpongeState.FixedOutputLength); end; end; procedure THash_SHA3Base.DoTransform(Buffer: PUInt32Array); begin // Empty on purpose as calculation is implemented differently for SHA3. Needed // to suppress the compiler warning that a class with an abstract method is created end; initialization // Define the has returned by ValidHash if passing nil as parameter SetDefaultHashClass(THash_SHA256); {$IFNDEF ManualRegisterClasses} THash_MD2.RegisterClass(TDECHash.ClassList); THash_MD4.RegisterClass(TDECHash.ClassList); THash_MD5.RegisterClass(TDECHash.ClassList); THash_RipeMD128.RegisterClass(TDECHash.ClassList); THash_RipeMD160.RegisterClass(TDECHash.ClassList); THash_RipeMD256.RegisterClass(TDECHash.ClassList); THash_RipeMD320.RegisterClass(TDECHash.ClassList); THash_SHA0.RegisterClass(TDECHash.ClassList); THash_SHA1.RegisterClass(TDECHash.ClassList); THash_SHA224.RegisterClass(TDECHash.ClassList); THash_SHA256.RegisterClass(TDECHash.ClassList); THash_SHA384.RegisterClass(TDECHash.ClassList); THash_SHA512.RegisterClass(TDECHash.ClassList); THash_SHA3_224.RegisterClass(TDECHash.ClassList); THash_SHA3_256.RegisterClass(TDECHash.ClassList); THash_SHA3_384.RegisterClass(TDECHash.ClassList); THash_SHA3_512.RegisterClass(TDECHash.ClassList); THash_Haval128.RegisterClass(TDECHash.ClassList); THash_Haval160.RegisterClass(TDECHash.ClassList); THash_Haval192.RegisterClass(TDECHash.ClassList); THash_Haval224.RegisterClass(TDECHash.ClassList); THash_Haval256.RegisterClass(TDECHash.ClassList); THash_Tiger.RegisterClass(TDECHash.ClassList); THash_Panama.RegisterClass(TDECHash.ClassList); {$IFDEF OLD_WHIRLPOOL_NAMES} THash_Whirlpool.RegisterClass(TDECHash.ClassList); THash_Whirlpool1.RegisterClass(TDECHash.ClassList); THash_Whirlpool1New.RegisterClass(TDECHash.ClassList); {$ELSE} THash_Whirlpool1.RegisterClass(TDECHash.ClassList); {$ENDIF} THash_Whirlpool0.RegisterClass(TDECHash.ClassList); THash_WhirlpoolT.RegisterClass(TDECHash.ClassList); THash_Square.RegisterClass(TDECHash.ClassList); THash_Snefru128.RegisterClass(TDECHash.ClassList); THash_Snefru256.RegisterClass(TDECHash.ClassList); THash_Sapphire.RegisterClass(TDECHash.ClassList); {$IFDEF OLD_SHA_NAME} THash_SHA.RegisterClass(TDECHash.ClassList); {$ENDIF} {$ENDIF} finalization // No need to unregister the hash classes, as the list is being freed // in finalization of DECBaseClass unit end.