unit GostBase; interface type { Номер слова ключа } tKeyWordIndex=0..15; tKeyDWordIndex=0..7; tDword=record W0,W1:word; end; { Ключ } tKey=record case Byte of 0:(Wds:array[tKeyWordIndex] of word); 1:(Dws:array[tKeyDWordIndex] of tDword); end; { Таблица подстановок } tSubstitutionTable=array[0..3,0..255] of byte; tDataUnitWordNumber=0..3; { Минимальная порция данных для криптопреобразования (4 слова)} tDataUnit=record case byte of 0:(Words:array[tDataUnitWordNumber] of word); 1:(W0,W1,W2,W3:word); end; (* tDataArrayIndex=0..( (High(word) div 8)-1 ); tDataArraySize=0.. Succ(High(tDataArrayIndex)); { Массив данных для криптопреобразования } tDataArray=array[tDataArrayIndex] of tDataUnit; tPDataArray=^tDataArray; *) var (* Преременные для индикации *) ME5,ME6,ME7,ME8,ME21,ME22,ME23,ME24: Byte; ME9,ME10,ME11,ME12,ME13,ME14,ME19,ME20: Word; { Основной шаг криптопреобразования } procedure BaseEncryptionStep( var ADataUnit:tDataUnit; const ASubstitutionTable:tSubstitutionTable; Key:tDword); {-------Основной цикл шифрования--------} procedure BaseEncodeSet( var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; Key:tKey); {-------Основной цикл расшифрования--------} procedure BaseDecodeSet( var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; Key:tKey); implementation uses prg_gost, indication; procedure BaseEncryptionStep( var ADataUnit:tDataUnit; const ASubstitutionTable: tSubstitutionTable; Key:tDword ); var xN1_h, xN1_l, tmp: Word; HiByte2, HiByte1: Byte; SumBit_l, SumBit_h, i: Integer; begin { Начало цикла } {1. Добавление к S ключа по модулю 2^32} xN1_l := ADataUnit.W0 or key.W0; xN1_h := ADataUnit.W1 or key.W1; { Заполняем переменные для индикации } ME20 := xN1_l; ME19 := xN1_h; ME8 := Lo(xN1_l); ME7 := Hi(xN1_l); ME6 := Lo(xN1_h); ME5 := Hi(xN1_h); { 2. Поблочная замена в S по таблице + вращение на 8 бит влево } HiByte1 := ASubstitutionTable[0, Lo(xN1_l)]; xN1_l := ASubstitutionTable[1, Hi(xN1_l)]; HiByte2 := ASubstitutionTable[2, Lo(xN1_h)]; xN1_h := ASubstitutionTable[3, Hi(xN1_h)]; tmp := xN1_l + HiByte2*256; xN1_l := xN1_h + HiByte1*256; xN1_h := tmp; { Заполняем переменные для индикации } ME21 := Lo(xN1_l); ME22 := Hi(xN1_h); ME23 := Lo(xN1_h); ME24 := Hi(xN1_l); ME10 := ME23*256+ME24; ME9 := ME21*256+ME22; { 3. Доворот S на 3 бита влево } i := 0; repeat if ((xN1_l shr 15) and 1) = 1 then begin xN1_l := xN1_l shl 1; SumBit_l := 1; end else begin xN1_l := xN1_l shl 1; SumBit_l := 0; end; if ((xN1_h shr 15) and 1) = 1 then begin xN1_h := xN1_h shl 1; SumBit_h := 1; end else begin xN1_h := xN1_h shl 1; SumBit_h := 0; end; xN1_l := xN1_l or SumBit_h; xN1_h := xN1_h or SumBit_l; i := i+1; until i = 3; { Заполняем переменные для индикации } ME12 := xN1_l; ME11 := xN1_h; { 4. Вычисление новых значений N1,N2 - операция XOR } xN1_l := xN1_l xor ADataUnit.W2; xN1_h := xN1_h xor ADataUnit.W3; { Заполняем переменные для индикации } ME14 := xN1_l; ME13 := xN1_h; { Копируем полученные шифроданные } ADataUnit.W3 := ADataUnit.W1; ADataUnit.W2 := ADataUnit.W0; ADataUnit.W1 := xN1_h; ADataUnit.W0 := xN1_l; { Конец цикла } end; procedure BaseEncodeSet( var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; Key:tKey ); var i,j: Integer; N_tmp: word; xKey: tDWord; begin {-------Начало базового цикла шифрования--------} {-------Основной цикл шифрования--------} for i:=1 to 3 do for j:=0 to 7 do begin; xKey.W1:=Key.Dws[j].W0; xKey.W0:=Key.Dws[j].W1; BaseEncryptionStep(AData, ASubstititionTable, xKey); temp_indication(AData, xKey, ME5,ME6,ME7,ME8,ME21,ME22,ME23,ME24, ME9,ME10,ME11,ME12,ME13,ME14,ME19,ME20); end; for j:=7 downto 0 do begin xKey.W1:=Key.Dws[j].W0; xKey.W0:=Key.Dws[j].W1; BaseEncryptionStep(AData, ASubstititionTable, xKey); temp_indication(AData, xKey, ME5,ME6,ME7,ME8,ME21,ME22,ME23,ME24, ME9,ME10,ME11,ME12,ME13,ME14,ME19,ME20); end; { В конце базового цикла меняем старшую и младшую части блока } N_tmp:=AData.W0; AData.W0:=AData.W2; AData.W2:=N_tmp; N_tmp:=AData.W1; AData.W1:=AData.W3; AData.W3:=N_tmp; {-------Конец базового цикла шифрования-------} end; procedure BaseDecodeSet( var AData:tDataUnit; const ASubstititionTable:tSubstitutionTable; Key:tKey ); var i,j: Integer; N_tmp: word; xKey: tDWord; begin {-------Начало базового цикла расшифрования-------} {-------Основной цикл расшифрования--------} for j:=0 to 7 do begin xKey.W1:=Key.Dws[j].W0; xKey.W0:=Key.Dws[j].W1; BaseEncryptionStep(AData, ASubstititionTable, xKey); temp_indication(AData, xKey, ME5,ME6,ME7,ME8,ME21,ME22,ME23,ME24, ME9,ME10,ME11,ME12,ME13,ME14,ME19,ME20); end; for i:=1 to 3 do for j:=7 downto 0 do begin xKey.W1:=Key.Dws[j].W0; xKey.W0:=Key.Dws[j].W1; BaseEncryptionStep(AData, ASubstititionTable, xKey); temp_indication(AData, xKey, ME5,ME6,ME7,ME8,ME21,ME22,ME23,ME24, ME9,ME10,ME11,ME12,ME13,ME14,ME19,ME20); end; { В конце базового цикла меняем старшую и младшую части блока } N_tmp:=AData.W0; AData.W0:=AData.W2; AData.W2:=N_tmp; N_tmp:=AData.W1; AData.W1:=AData.W3; AData.W3:=N_tmp; temp_indication(AData, xKey, ME5,ME6,ME7,ME8,ME21,ME22,ME23,ME24, ME9,ME10,ME11,ME12,ME13,ME14,ME19,ME20); {-------Конец базового цикла расшифрования-------} end; end.