{ / 23147-89 } { ஢/஢ 23147-89 } {--------------------------------------------------------------------------- (c) Copyright Aleksandrov O.E., 2006 Molecular Physics department, USTU, Ekaterinsburg, K-2, 620002, RUSSIA phone 375-41-46 E-mail: aleks@dpt.ustu.ru (c) Copyright .., 2006 620002, , -2, , . 375-41-46 E-mail: aleks@dpt.ustu.ru ----------------------------------------------------------------------------} Unit GostBase; INTERFACE { ⨯ ॠ樨 ⬠ -89 } { -89 } const { } gostgamma_C1=$1010104; gostgamma_C2=$1010101; type { ᫮ } { } tKeyWordIndex=0..15; { ᫮ } { } tKeyDWordIndex=0..7; { ᫮ - 32-⭮ 楫 } { - 32- } tDword=packed record case Byte of {$IfDef Delphi} 0:(DW:LongWord); {$EndIf} 1:(W0,W1:word); 2:(Bytes:packed array[0..3] of byte); 3:(Words:packed array[0..1] of word); end; { } { } tKey=record case Byte of 0:(Wds:packed array[tKeyWordIndex] of word); 1:(Dws:packed array[tKeyDWordIndex] of tDword); end; { ⠭, ᠭ -89 } { , -89 } tBstElement=0..15; tBstRowNumber=0..7; tBstColNumber=0..15; tBaseSubstitutionTableRow=packed array[tBstColNumber] of tBstElement; tBaseSubstitutionTable=packed array[tBstRowNumber] of tBaseSubstitutionTableRow; { ७ ⠡ ⠭ - 楫, ᯮ 㡠 } { - , } tStRowNumber=0..3; tStColNumber=byte; tSubstitutionTable=packed array[tStRowNumber, tStColNumber] of byte; { - , } tXstRowNumber=0..1; tXstColNumber=word; tXSubstitutionTable=packed array[tXstRowNumber, tXstColNumber] of word; { 쭠 ਯ⮯८ࠧ (64 )} { (64 )} tDataUnitByteNumber=0..7; tDataUnitWordNumber=0..3; tDataUnitDWordNumber=0..1; tDataUnit=packed record case byte of 0:(Bytes:packed array[tDataUnitByteNumber] of byte); 1:(Words:packed array[tDataUnitWordNumber] of word); 2:(W0,W1,W2,W3:word); 3:(DWs:packed array[tDataUnitDWordNumber] of tDword); 4:(DW0,DW1:tDword); end; { ᨢ () ਯ⮯८ࠧ } { () } tDataArrayIndex=0..{$IfDef Delphi}( (High(integer) div 8)-1 ){$Else}( (High(word) div 8)-1 ){$EndIf}; tDataArraySize=0.. Succ(High(tDataArrayIndex)); tDataArray=packed array[tDataArrayIndex] of tDataUnit; tPDataArray=^tDataArray; { == end type == 樨 ⨯} { == end type == } {८ࠧ ⠡ ⠭ ଠ, 騩 ⠢ ⭮} { , (8 )} procedure ExpandSubstitutionTable( const aBaseTable:tBaseSubstitutionTable; var aExpandedTable:tSubstitutionTable ); { , c (16 )} procedure ExpandXSubstitutionTable( const aBaseTable:tBaseSubstitutionTable; var aExpandedTable:tXSubstitutionTable ); { ᭮ 蠣 ਯ⮯८ࠧ } { } procedure BaseEncryptionStep( var aDataUnit:tDataUnit; const aSubstitutionTable:tSubstitutionTable; aKey:tDword );{$IfDef Delphi} register; {$EndIf} { ( )} procedure BaseEncryptionStepX( var aDataUnit:tDataUnit; const aSubstitutionTable:tXSubstitutionTable; aKey:tDword );{$IfDef Delphi} register; {$EndIf} { ᭮ 蠣 ਯ⮯८ࠧ - ᥬ ਠ} { - } procedure asmBaseEncryptionStep( var ADataUnit:tDataUnit; const ASubstitutionTable:tSubstitutionTable; Key:tDword );{$IfDef Delphi} register; {$EndIf} { 楤 ஢ 쭮 樨 } { } procedure Encrypt(var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; const Key:tKey ); { - } procedure EncryptX(var AData:tDataUnit; const ASubstititionTable:tXSubstitutionTable; const Key:tKey ); { 楤 ஢ 쭮 樨 } { } procedure Decrypt(var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; const Key:tKey ); { - } procedure DecryptX(var AData:tDataUnit; const ASubstititionTable:tXSubstitutionTable; const Key:tKey ); { 楤 ஢ ᨢ } { - } procedure EncryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey ); { - } procedure ExEncryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey ); { - } procedure ExEncryptArrayX( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tXSubstitutionTable; const Key:tKey ); { - - } procedure xEncryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey );{$IfDef Delphi} register; {$EndIf} { 楤 ஢ ᨢ } { - } procedure DecryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey ); { - } procedure ExDecryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey ); { - } procedure ExDecryptArrayX( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tXSubstitutionTable; const Key:tKey ); { - - } procedure xDecryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey );{$IfDef Delphi} register; {$EndIf} { aDataUnit 砩묨 祭ﬨ 稭 aStartByte} { aDataUnit aStartByte} procedure RandomDataUnit(var aDataUnit:tDataUnit; aStartByte:tDataUnitByteNumber); { !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} { aDataUnit, aDataUnit } procedure Gamma(var aDataUnit:tDataUnit); { - } procedure GammaEncrypt( var aData:tDataUnit; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tSubstitutionTable; const aKey:tKey ); procedure GammaEncryptX( var aData:tDataUnit; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tXSubstitutionTable; const aKey:tKey ); { } procedure GammaEncryptArray( var aData:tDataArray; aDataSize:tDataArraySize; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tSubstitutionTable; const aKey:tKey ); procedure GammaEncryptArrayX( var aData:tDataArray; aDataSize:tDataArraySize; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tXSubstitutionTable; const aKey:tKey ); IMPLEMENTATION { aDataUnit 砩묨 祭ﬨ 稭 aStartByte} { aDataUnit aStartByte} procedure RandomDataUnit(var aDataUnit:tDataUnit; aStartByte:tDataUnitByteNumber); var i:tDataUnitByteNumber; begin Randomize; for i:=aStartByte to high(i) do begin aDataUnit.Bytes[i]:=Random(high(byte)+1); end; end; {८ࠧ ⠡ ⠭ ଠ, 騩 ⠢ ⭮} { , } procedure ExpandSubstitutionTable( const aBaseTable:tBaseSubstitutionTable; var aExpandedTable:tSubstitutionTable ); var j:tStRowNumber; j0,j1:tBstColNumber; begin for j:=low(j) to high(j) do begin for j0:=low(j0) to high(j0) do begin for j1:=low(j1) to high(j1) do begin aExpandedTable[j][j0 or (j1 shl 4)]:= aBaseTable[j+j][j0] or (aBaseTable[j+j+1][j1] shl 4); end; end; end; end; { , } procedure ExpandXSubstitutionTable( const aBaseTable:tBaseSubstitutionTable; var aExpandedTable:tXSubstitutionTable ); var j:tXstRowNumber; j0,j1,j2,j3:tBstColNumber; begin for j:=low(j) to high(j) do begin for j0:=low(j0) to high(j0) do begin for j1:=low(j1) to high(j1) do begin for j2:=low(j2) to high(j2) do begin for j3:=low(j3) to high(j3) do begin aExpandedTable[j][word(j0) or (j1 shl 4) or (j2 shl 8) or (j3 shl 12)]:= word(aBaseTable[4*j][j0]) or (aBaseTable[4*j+1][j1] shl 4) or (aBaseTable[4*j+2][j2] shl 8) or (aBaseTable[4*j+3][j3] shl 12) ; end; end; end; end; end; end; procedure Add(var Value:tDword; Key:tDword); near; {$IfNDef Delphi} assembler; asm les si,Value mov AX,es:word([si])[0] add AX,key.W0; mov es:word([si])[0],AX mov AX,es:word([si])[2] adc AX,key.W1; mov es:word([si])[2],AX end; {$Else IfNDef Delphi} register; asm add [Value],Key end; {$EndIf NDef Delphi} procedure ExchangeData(var X:tDataUnit); near; {$IfNDef Delphi} assembler; asm les si,X mov cx,word(es:[si]) xchg word(es:[si][4]),cx mov word(es:[si]),cx mov cx,word(es:[si][2]) xchg word(es:[si][6]),cx mov word(es:[si][2]),cx end; {$Else IfNDef Delphi} register; asm mov EDX, [X].DW0 mov ECX, [X].DW1 mov [X].DW1, EDX mov [X].DW0, ECX { mov EDX, [X].DW0 xchg [X].DW1, EDX mov [X].DW0, EDX } end; {$EndIf NDef Delphi} { 蠣 ⮯८ࠧ } { } procedure BaseEncryptionStep( var aDataUnit:tDataUnit; const aSubstitutionTable:tSubstitutionTable; aKey:tDword ); {$IfNDef Delphi} var b:byte;{$EndIf} begin { 1. dw0 2^32} { 1. dw0 2^32} {$IfNDef Delphi} Add(aKey, aDataUnit.DW0.dw); {$Else IfNDef Delphi} {$IfOpt Q+} aKey.dw:=(int64(aDataUnit.DW0.dw)+aKey.dw) AND high(aKey.dw); {$Else } aKey.dw:=(aDataUnit.DW0.dw+aKey.dw); {$EndIf} {$EndIf NDef Delphi} { 2. 筠 dw0 饭 8 . ਬ ७ ⠡ , ࠧ } { 2. dw0. , } aKey.dw:=aSubstitutionTable[0, aKey.Bytes[0]] or aSubstitutionTable[1, aKey.Bytes[1]] shl 8 or aSubstitutionTable[2, aKey.Bytes[2]] shl 16 or aSubstitutionTable[3, aKey.Bytes[3]] shl 24; { 3. dw0 11 } { 3. dw0 11 } {$IfDef Delphi} {$IfOpt Q+} aKey.dw:=(((aKey.dw and $1FFFFF) shl 11) or (aKey.dw shr 21)) xor aDataUnit.DW1.dw; {$Else } aKey.dw:=((aKey.dw shl 11) or (aKey.dw shr 21)) xor aDataUnit.DW1.dw; {$EndIf} {$Else} b:=aKey.w1 shr 5; {b = 訥 5 dw0.w1} aKey.w1:=((aKey.w1 and $1F) shl 11) or (aKey.w0 shr 5); { 1Fh = 0000000000011111b } aKey.w0:=((aKey.w0 and $1F) shl 11) or b; {$EndIf} { 4. ⮢ ᫮ dw0 訬 4- ⠬ 㥬 } { 4. dw0 4- } {$IfDef Delphi} {$Else} aKey.w0:=aKey.w0 xor aDataUnit.DW1.w0; aKey.w1:=aKey.w1 xor aDataUnit.DW1.w1; {$EndIf} { 5. 4- 㥬 4- } { 5. 4- 4- } aDataUnit.DW1:=aDataUnit.DW0; { 4- dw0 } { 4- dw0 } aDataUnit.DW0:=aKey; { 6. 頥 ८ࠧ } { 6. } end; { - } procedure BaseEncryptionStepX( var aDataUnit:tDataUnit; const aSubstitutionTable:tXSubstitutionTable; aKey:tDword ); {$IfNDef Delphi} var b:byte;{$EndIf} begin { 4 ८ࠧ㥬 , 訥 4- 㥬 } { 4 , 4- } { 1. dw0 2^32} { 1. dw0 2^32} {$IfNDef Delphi} Add(dw0, aKey); {$Else IfNDef Delphi} {$IfOpt Q+} aKey.dw:=(aDataUnit.DW0.dw+int64(aKey.dw)) AND high(aKey.dw); {$Else } Inc(aKey.dw, aDataUnit.DW0.dw); {$EndIf} {$EndIf NDef Delphi} { 2. 筠 dw0 饭 8 . ਬ ७ ⠡ , ࠧ } { 2. dw0. , } aKey.dw:=aSubstitutionTable[0, aKey.W0] OR (aSubstitutionTable[1, aKey.W1] shl 16); { 3. dw0 11 } { 3. dw0 11 } {$IfDef Delphi} {$IfOpt Q+} aKey.dw:=(((aKey.dw and $1FFFFF) shl 11) or (aKey.dw shr 21)) xor aDataUnit.DW1.dw; {$Else } aKey.dw:=((aKey.dw shl 11) or (aKey.dw shr 21)) xor aDataUnit.DW1.dw; {$EndIf} {$Else} b:=aKey.w1 shr 5; {b = 訥 5 dw0.w1} aKey.w1:=((aKey.w1 and $1F) shl 11) or (aKey.w0 shr 5); { 1Fh = 0000000000011111b } aKey.w0:=((aKey.w0 and $1F) shl 11) or b; {$EndIf} { 4. ⮢ ᫮ dw0 訬 4- ⠬ 㥬 } { 4. dw0 4- } {$IfDef Delphi} { 3.} {$Else} aKey.w0:=aKey.w0 xor aDataUnit.DW1.w0; aKey.w1:=aKey.w1 xor aDataUnit.DW1.w1; {$EndIf} { 5. 4- 㥬 4- } { 5. 4- 4- } aDataUnit.DW1:=aDataUnit.DW0; { 4- dw0 } { 4- dw0 } aDataUnit.DW0:=aKey; { 6. 頥 ८ࠧ } { 6. } end; { - } procedure asmBaseEncryptionStep( var ADataUnit:tDataUnit; const ASubstitutionTable:tSubstitutionTable; Key:tDword ); {$IfNDef Delphi} assembler; asm { ࠭塞 ॣ } pusha; { 1. 4 㥬 S=AX:DX } les si,ADataUnit mov AX,es:word([si])[0]; mov DX,es:word([si])[2]; { 1. ࠭塞 4 㥬 ॣ DI:CX } mov DI,AX; mov CX,DX; { 2. S 2^32} add AX,key.W0; adc DX,key.W1; { 3. 筠 S 饭 8 } { ⠡ } lds BX,ASubstitutionTable xlat; xchg AH,AL; inc BH; xlat; xchg DL,AL; inc BH; xlat; xchg DH,AL; inc BH; xlat; { 4. S 3 } shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; { 5. ᫥ 祭 N1,N2} xor DX,es:word([si])[6]; xor AX,es:word([si])[4]; { 㥬 祭 த ॣ஢ } mov es:word([si])[0],AX; mov es:word([si])[2],DX; mov es:word([si])[4],DI; mov es:word([si])[6],CX; { ⠭ ॣ } popa; end; {$Else IfNDef Delphi} { EAX->ADataUnit EDX -> ASubstitutionTable ECX := Key } asm { } push ebx mov EBX,ASubstitutionTable { 1. 4 } mov EDX,[ADataUnit] { 2. 2^32} add Key,EDX xchg EDX,[ADataUnit][4] xchg ADataUnit,Key { 3. 8 } xlat ror EAX,8; inc BH; xlat ror EAX,8; inc BH; xlat ror EAX,8; inc BH; xlat; { 4. 3 } rol EAX,3 { 5. } xor EAX,EDX { } mov [ECX],EAX; { } pop ebx end; {$EndIf NDef Delphi} { ⮥ ஢ 筮 tDataUnit-} { tDataUnit-} procedure Encrypt(var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; //tmp:tDword; begin for k:=2 downto 0 do begin for i:=low(i) to high(i) do begin {$IfDef ASM } xBaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$Else} BaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$EndIf} end; end; for i:=high(i) downto low(i) do begin {$IfDef ASM } xBaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$Else} BaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$EndIf} end; ExchangeData(aData); end; procedure EncryptX(var AData:tDataUnit; const ASubstititionTable:tXSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; begin for k:=2 downto 0 do begin for i:=low(i) to high(i) do begin BaseEncryptionStepX(AData,ASubstititionTable,key.Dws[i]); end; end; for i:=high(i) downto low(i) do begin BaseEncryptionStepX(AData,ASubstititionTable,key.Dws[i]); end; ExchangeData(aData); end; { ⮥ ஢ ᨢ tDataUnit-} { tDataUnit-} procedure EncryptArray( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tSubstitutionTable; const Key:tKey ); var i:tDataArrayIndex; begin for i:=Pred(aDataSize) downto low(i) do begin Encrypt(aData[i], aSubstitutionTable, Key); end; end; { ஥ ஢ ᨢ tDataUnit} { tDataUnit} procedure ExEncryptArray( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; tmp:tDword; n:tDataArrayIndex; begin for k:=2 downto 0 do begin for i:=low(i) to high(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin {$IfDef ASM } xBaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$Else} BaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$EndIf} end; end; end; for i:=high(i) downto low(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin {$IfDef ASM } xBaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$Else} BaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$EndIf} end; end; for n:=Pred(aDataSize) downto low(n) do begin ExchangeData(aData[n]); end; end; { tDataUnit} procedure ExEncryptArrayX( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tXSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; tmp:tDword; n:tDataArrayIndex; begin for k:=2 downto 0 do begin for i:=low(i) to high(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin BaseEncryptionStepX(aData[n], aSubstitutionTable, tmp); end; end; end; for i:=high(i) downto low(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin BaseEncryptionStepX(aData[n], aSubstitutionTable, tmp); end; end; for n:=Pred(aDataSize) downto low(n) do begin ExchangeData(aData[n]); end; end; { ⮥ ஢ 筮 tDataUnit-} { tDataUnit-} procedure Decrypt(var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; begin for i:=low(i) to High(i) do begin {$IfDef ASM } xBaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$Else} BaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$EndIf} end; for k:=2 downto 0 do begin for i:=high(i) downto low(i) do begin {$IfDef ASM } xBaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$Else} BaseEncryptionStep(AData,ASubstititionTable,key.Dws[i]); {$EndIf} end; end; ExchangeData(aData); end; procedure DecryptX(var AData:tDataUnit; const ASubstititionTable:tXSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; begin for i:=low(i) to High(i) do begin BaseEncryptionStepX(AData,ASubstititionTable,key.Dws[i]); end; for k:=2 downto 0 do begin for i:=high(i) downto low(i) do begin BaseEncryptionStepX(AData,ASubstititionTable,key.Dws[i]); end; end; ExchangeData(aData); end; { ⮥ ஢ ᨢ tDataUnit-} { tDataUnit-} procedure DecryptArray( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tSubstitutionTable; const Key:tKey ); var i:tDataArrayIndex; begin for i:=Pred(aDataSize) downto low(i) do begin Decrypt(aData[i], aSubstitutionTable, Key); end; end; { ஥ ஢ ᨢ tDataUnit} { tDataUnit} procedure ExDecryptArray( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; tmp:tDword; n:tDataArrayIndex; begin for i:=low(i) to High(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin {$IfDef ASM } xBaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$Else} BaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$EndIf} end; end; for k:=2 downto 0 do begin for i:=high(i) downto low(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin {$IfDef ASM } xBaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$Else} BaseEncryptionStep(aData[n], aSubstitutionTable, tmp); {$EndIf} end; end; end; for n:=Pred(aDataSize) downto low(n) do begin ExchangeData(aData[n]); end; end; { tDataUnit} procedure ExDecryptArrayX( var aData:tDataArray; aDataSize:tDataArraySize; const aSubstitutionTable:tXSubstitutionTable; const Key:tKey ); var i:tKeyDWordIndex; k:byte; tmp:tDword; n:tDataArrayIndex; begin for i:=low(i) to High(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin BaseEncryptionStepX(aData[n], aSubstitutionTable, tmp); end; end; for k:=2 downto 0 do begin for i:=high(i) downto low(i) do begin tmp:=key.Dws[i]; for n:=Pred(aDataSize) downto low(n) do begin BaseEncryptionStepX(aData[n], aSubstitutionTable, tmp); end; end; end; for n:=Pred(aDataSize) downto low(n) do begin ExchangeData(aData[n]); end; end; procedure xEncryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey ); {$IfNDef Delphi} assembler; var k:byte; j:word; Key_Lo,Key_Hi:word; n:tDataArraySize; asm {-------᭮ 横 ஢--------} pusha; mov cx,ADataSize or cx,cx; jnz @Start; jmp @End @Start: cld les bx,ASubstitutionTable; mov k,3 @LoopK: mov j,0 @LoopI: lds si,Key add si,j lodsw; mov Key_Lo,ax lodsw; mov Key_Hi,ax lds si,AData; mov ax,ADataSize; mov n,ax @LoopN: { 1. 㦠 4 㥬 } mov AX,[si][0]; mov DX,[si][2]; mov DI,AX; mov CX,DX; { 2. S 2^32} add AX,key_Lo; adc DX,key_Hi; { 3. 筠 S 饭 8 } xlat; xchg AH,AL; inc BH; xlat; xchg DL,AL; inc BH; xlat; xchg DH,AL; inc BH; xlat; sub bh,3 { 4. S 3 } shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; { 5. ᫥ 祭 N1,N2} xor DX,[si][6]; xor AX,[si][4]; { 㥬 祭 த ॣ஢ } mov [si][0],AX; mov [si][2],DX; mov [si][4],DI; mov [si][6],CX; dec n; jz @EndN add si,8 jmp @LoopN @EndN: add j,4; cmp j,28; ja @EndI jmp @LoopI @EndI: dec k; jz @EndK jmp @LoopK @EndK: mov j,28 @LoopI1: lds si,Key add si,j lodsw; mov Key_Lo,ax lodsw; mov Key_Hi,ax lds si,AData; mov ax,ADataSize; mov n,ax @LoopN1: { 1. 㦠 4 㥬 } mov AX,[si][0]; mov DX,[si][2]; mov DI,AX; mov CX,DX; { 2. S 2^32} add AX,key_Lo; adc DX,key_Hi; { 3. 筠 S 饭 8 } xlat; xchg AH,AL; inc BH; xlat; xchg DL,AL; inc BH; xlat; xchg DH,AL; inc BH; xlat; sub bh,3 { 4. S 3 } shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; { 5. ᫥ 祭 N1,N2} xor DX,[si][6]; xor AX,[si][4]; { 㥬 祭 த ॣ஢ } mov [si][0],AX; mov [si][2],DX; mov [si][4],DI; mov [si][6],CX; dec n; jz @EndN1 add si,8 jmp @LoopN1 @EndN1: sub j,4; jc @EndI1 jmp @LoopI1 @EndI1: { 横 塞 } lds si,AData; les di,AData; add di,4 mov cx,ADataSize @LoopN3: mov ax,[di] movsw {mov [di],[si]; add di,2; add si,2} mov [si-2],ax mov ax,[di] movsw {mov [di],[si]; add di,2; add si,2} mov [si-2],ax add si,4; add di,4 loop @LoopN3 @End: popa; end; {$Else IfNDef Delphi} { EAX-> AData; EDX = ADataSize; ECX-> ASubstitutionTable; ⥪: Key} var k:byte; j,KeyDW:tDword; n:tDataArraySize; lDataSize:tDataArraySize; asm {------- --------} pushad; or ADataSize,ADataSize; jnz @Start; jmp @End @Start: mov lDataSize,ADataSize cld mov ebx,ASubstitutionTable; mov edi,AData mov k,3 @LoopK: mov j,0 @LoopI: mov esi,Key add esi,j lodsd; mov KeyDW,eax mov esi,edi mov eax,lDataSize; mov n,eax @LoopN: { 1. 4 } mov EAX,[esi]; mov EDX,EAX; xchg EDX,[esi][4] { 2. S 2^32} add EAX,KeyDW { 3. S 8 } xlat ror EAX,8; inc BH; xlat ror EAX,8; inc BH; xlat ror EAX,8; inc BH; xlat sub bh,3 { 4. S 3 } rol EAX,3 { 5. N1,N2} xor EAX,EDX; { } mov [esi],EAX; dec n; jz @EndN add esi,8 jmp @LoopN @EndN: add j,4; cmp j,28; ja @EndI jmp @LoopI @EndI: dec k; jz @EndK jmp @LoopK @EndK: mov j,28 @LoopI1: mov esi,Key add esi,j lodsd; mov KeyDW,eax mov esi,edi; mov eax,lDataSize; mov n,eax @LoopN1: { 1. 4 } mov EAX,[esi] mov EDX,EAX xchg EDX,[esi][4] { 2. S 2^32} add EAX,KeyDw; { 3. S 8 } xlat ror EAX,8; inc BH; xlat ror EAX,8; inc BH; xlat ror EAX,8; inc BH; xlat sub bh,3 { 4. S 3 } rol EAX,3 { 5. N1,N2} xor EAX,EDX { } mov [esi],EAX; dec n; jz @EndN1 add si,8 jmp @LoopN1 @EndN1: sub j,4; jc @EndI1 jmp @LoopI1 @EndI1: { } mov esi,edi; add di,4 mov ecx,lDataSize @LoopN3: mov eax,[edi] movsd mov [esi-4],eax add esi,4; add edi,4 loop @LoopN3 @End: popad; end; {$EndIf NDef Delphi} procedure xDecryptArray( var AData:tDataArray; ADataSize:tDataArraySize; const ASubstitutionTable:tSubstitutionTable; const Key:tKey ); {$IfNDef Delphi} assembler; var k:byte; j:word; Key_Lo,Key_Hi:word; n:tDataArraySize; asm {-------᭮ 横 ஢--------} pusha; mov cx,ADataSize or cx,cx; jnz @Start; jmp @End @Start: cld les bx,ASubstitutionTable; mov j,0 @LoopI1: lds si,Key add si,j lodsw; mov Key_Lo,ax lodsw; mov Key_Hi,ax lds si,AData; mov cx,ADataSize; mov n,CX @LoopN1: { 1. 㦠 4 㥬 } mov AX,[si][0]; mov DX,[si][2]; mov DI,AX; mov CX,DX; { 2. S 2^32} add AX,key_Lo; adc DX,key_Hi; { 3. 筠 S 饭 8 } xlat; xchg AH,AL; inc BH; xlat; xchg DL,AL; inc BH; xlat; xchg DH,AL; inc BH; xlat; sub bh,3 { 4. S 3 } shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; { 5. ᫥ 祭 N1,N2} xor DX,[si][6]; xor AX,[si][4]; { 㥬 祭 த ॣ஢ } mov [si][0],AX; mov [si][2],DX; mov [si][4],DI; mov [si][6],CX; dec n; jz @EndN1 add si,8 jmp @LoopN1 @EndN1: add j,4; cmp j,28; ja @EndI1 jmp @LoopI1 @EndI1: mov k,3 @LoopK: mov j,28 @LoopI: lds si,Key add si,j lodsw; mov Key_Lo,ax lodsw; mov Key_Hi,ax lds si,AData; mov cx,ADataSize; mov n,CX @LoopN: { 1. 㦠 4 㥬 } mov AX,[si][0]; mov DX,[si][2]; mov DI,AX; mov CX,DX; { 2. S 2^32} add AX,key_Lo; adc DX,key_Hi; { 3. 筠 S 饭 8 } xlat; xchg AH,AL; inc BH; xlat; xchg DL,AL; inc BH; xlat; xchg DH,AL; inc BH; xlat; sub bh,3 { 4. S 3 } shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; shl AX,1; rcl DX,1; adc AX,0; { 5. ᫥ 祭 N1,N2} xor DX,[si][6]; xor AX,[si][4]; { 㥬 祭 த ॣ஢ } mov [si][0],AX; mov [si][2],DX; mov [si][4],DI; mov [si][6],CX; dec n; jz @EndN add si,8 jmp @LoopN @EndN: sub j,4; jc @EndI jmp @LoopI @EndI: dec k; jz @EndK jmp @LoopK @EndK: { 横 塞 } lds si,AData; les di,AData; add di,4 mov cx,ADataSize @LoopN3: mov ax,[di] movsw {mov [di],[si]; add di,2; add si,2} mov [si-2],ax mov ax,[di] movsw {mov [di],[si]; add di,2; add si,2} mov [si-2],ax add si,4; add di,4 loop @LoopN3 @End: popa; end; {$Else IfNDef Delphi} asm end; {$EndIf NDef Delphi} { X gostgamma_C2 (2^32-1) - ??? } function AddC1(var X:LongWord):LongWord; assembler; asm xor edx,edx { edx:=0} add LongWord([X]),gostgamma_C1 {LongWord([X]):=(LongWord([X])+gostgamma_C2) mod 2^32; CF:=(LongWord([X])+gostgamma_C2)>2^32} adc edx,0 {+1 >2^32} { edx:=edx+CF } add LongWord([X]),1; adc edx,0; sub LongWord([X]),1; {+1 =2^32} {CF:=(LongWord([X])+gostgamma_C2)=2^32 } add LongWord([X]),edx { if (LongWord([X])+gostgamma_C2)>=2^32 then LongWord([X]):=LongWord([X])+1} end; { aDataUnit, aDataUnit } procedure Gamma(var aDataUnit:tDataUnit); begin {$IfOpt Q+} aDataUnit.DW0:=(int64(aDataUnit.DW0)+gostgamma_C2) and $FFFFFFFF; AddC1(aDataUnit.DW1); {$Else } Inc(aDataUnit.DW0.DW, gostgamma_C2); AddC1(aDataUnit.DW1.DW); {$EndIf} end; { - } procedure GammaEncrypt( var aData:tDataUnit; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tSubstitutionTable; const aKey:tKey ); var x:tDataUnit; begin Gamma(aGammaDataUnit); x:=aGammaDataUnit; Encrypt(x, aSubstititionTable, aKey); aData.DW0.DW:=aData.DW0.DW xor x.DW0.DW; aData.DW1.DW:=aData.DW1.DW xor x.DW1.DW; end; procedure GammaEncryptX( var aData:tDataUnit; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tXSubstitutionTable; const aKey:tKey ); var x:tDataUnit; begin Gamma(aGammaDataUnit); x:=aGammaDataUnit; EncryptX(x, aSubstititionTable, aKey); aData.DW0.DW:=aData.DW0.DW xor x.DW0.DW; aData.DW1.DW:=aData.DW1.DW xor x.DW1.DW; end; { / } procedure GammaEncryptArray( var aData:tDataArray; aDataSize:tDataArraySize; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tSubstitutionTable; const aKey:tKey ); var x:tDataUnit; n:tDataArrayIndex; begin for n:=low(n) to Pred(aDataSize) do begin Gamma(aGammaDataUnit); x:=aGammaDataUnit; Encrypt(x, aSubstititionTable, aKey); with aData[n] do begin DW0.DW:=DW0.DW xor x.DW0.DW; DW1.DW:=DW1.DW xor x.DW1.DW; end; end; end; procedure GammaEncryptArrayX( var aData:tDataArray; aDataSize:tDataArraySize; var aGammaDataUnit:tDataUnit; const aSubstititionTable:tXSubstitutionTable; const aKey:tKey ); var x:tDataUnit; n:tDataArrayIndex; begin for n:=low(n) to Pred(aDataSize) do begin Gamma(aGammaDataUnit); x:=aGammaDataUnit; EncryptX(x, aSubstititionTable, aKey); with aData[n] do begin DW0.DW:=DW0.DW xor x.DW0.DW; DW1.DW:=DW1.DW xor x.DW1.DW; end; end; end; end.