Main step of GOST 28147-89

From Rosetta Code
Revision as of 20:02, 31 August 2012 by rosettacode>Русский (New task.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Main step of GOST 28147-89
You are encouraged to solve this task according to the task description, using any language you may know.

GOST 28147-89 is a standard symmetric encryption. Structure of the algorithm consists of three levels:

1) encryption modes - simple replacement, application range, imposing a range of feedback and authentication code generation;

2) cycles - 32-З, 32-Р and 16-З, is a repetition of the main step;

3) main step, a function that takes a 64-bit block of text and one of the eight 32-bit encryption key elements, and uses the replacement table (8x16 matrix of 4-bit values), and returns encrypted block.

C

Version with packed replacement table.

<lang C>static unsigned char k87[256]; static unsigned char k65[256]; static unsigned char k43[256]; static unsigned char k21[256];

void kboxinit(void) { int i; for (i = 0; i < 256; i++) { k87[i] = k8[i >> 4] << 4 | k7[i & 15]; k65[i] = k6[i >> 4] << 4 | k5[i & 15]; k43[i] = k4[i >> 4] << 4 | k3[i & 15]; k21[i] = k2[i >> 4] << 4 | k1[i & 15]; } }

static word32 f(word32 x) { x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 | k43[x>> 8 & 255] << 8 | k21[x & 255]; return x<<11 | x>>(32-11); }</lang>

JavaScript

<lang JavaScript>function ОсновнойШаг(блок_текста, элемент_ключа) {

 var N = блок_текста.slice(0);
 var X = элемент_ключа;
 var S = (N[0] + X) & 0xFFFFFFFF;
 var ячейка; var нов_S = 0;
 for (var сч = 0; сч < 4; сч++) {
   ячейка = (S >>> (сч << 3)) & 0xFF;
   нов_S += (ТаблицаЗамен[сч*2][ячейка & 0x0F] + (ТаблицаЗамен[сч*2+1][ячейка >>> 4] << 4)) << (сч << 3);
 }
 S = (((нов_S << 11) + (нов_S >>> 21)) & 0xFFFFFFFF) ^ N[1];
 N[1] = N[0]; N[0] = S;
 return N;

}</lang>

Note: the variable "блок_текста" is an array of two 32-bit values that make up the block.

Glagol

ЗАДАЧА ОсновнойШаг(N: ШИРЦЕЛ; X: ЦЕЛ): ШИРЦЕЛ; 
ПЕР 
  N1, N2, S: ЦЕЛ; 
  сч: ЯЧЦЕЛ; 
  ячейка: ЯЧЦЕЛ; 
  результат: ШИРЦЕЛ; 
  ЗАДАЧА Замена(стр: ЯЧЦЕЛ; яч: ОБХОД.Ячейка): ЯЧЦЕЛ; 
  ПЕР 
    п1, п2, п3: ЦЕЛ; результат: ЯЧЦЕЛ;
  УКАЗ 
    п1 := 0; п2 := 0; ОБХОД.Образ(ОБХОД.ПолучитьАдрес(яч), ОБХОД.ПолучитьАдрес(п1), 1); 
    п1 := Асм.Сдвиг(п1, 4); ОБХОД.Образ(ОБХОД.ПолучитьАдрес(п1), ОБХОД.ПолучитьАдрес(п2), 1); 
    п2 := Асм.Сдвиг(п2, -4); п1 := Асм.Сдвиг(п1, -8); 
    п3 := ТаблицаЗамен[стр*2, п2] + Асм.Сдвиг(ТаблицаЗамен[стр*2+1, п1], 4); 
    ОБХОД.Образ(ОБХОД.ПолучитьАдрес(п3), ОБХОД.ПолучитьАдрес(результат), 1); 
    ВОЗВРАТ результат
  КОН Замена; 
УКАЗ 
  ОБХОД.Образ(ОБХОД.ПолучитьАдрес(N), ОБХОД.ПолучитьАдрес(N1), 4); 
  ОБХОД.Образ(ОБХОД.ПолучитьАдрес(N)+4, ОБХОД.ПолучитьАдрес(N2), 4); 
  S := БеззнСлжПоМод32(N1, X); 
  ОТ сч := 0 ДО 3 ВЫП 
    ОБХОД.Образ(ОБХОД.ПолучитьАдрес(S)+сч, ОБХОД.ПолучитьАдрес(ячейка), 1); 
    ячейка := Замена(сч, ячейка); 
    ОБХОД.Образ(ОБХОД.ПолучитьАдрес(ячейка), ОБХОД.ПолучитьАдрес(S)+сч, 1) 
  КОН; 
  S := Асм.Вращение(S, 11); 
  S := ИсклИЛИ(S, N2); 
  N2 := N1; N1 := S; 
  ОБХОД.Образ(ОБХОД.ПолучитьАдрес(N1), ОБХОД.ПолучитьАдрес(результат), 4); 
  ОБХОД.Образ(ОБХОД.ПолучитьАдрес(N2), ОБХОД.ПолучитьАдрес(результат)+4, 4); 
  ВОЗВРАТ результат 
КОН ОсновнойШаг;