Main step of GOST 28147-89: Difference between revisions
No edit summary |
|||
Line 7: | Line 7: | ||
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. |
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. |
||
=={{header|X86 Assembly}}== |
|||
Parameter in the call: |
|||
* EAX - the youngest part of the transformed block (N1); |
|||
* EDX - leading part transformed block (N2); |
|||
* ESI - address of the first element of the key; |
|||
* EBX - table address changes; |
|||
* ECX - the number of major steps. |
|||
Output results: |
|||
* EDX = N1, EAX = N2 for cycles 32-З, 32-Р; |
|||
* EAX = N1, EDX = N2 for cycle 16-З. |
|||
Register Usage: all except EDI. |
|||
Notes: |
|||
* At the end of the run the registers as follows: |
|||
* EBX (table pointer changes) - the same as that in the early |
|||
* ESI (index key) - points to the first byte of the key - it's N * 4 larger than the initial values for the SI cycle reps H (for encryption cycles N = 32 => 4 * N = 128, for authentication code generation cycle N = 16 => 4 * N = 64), larger than the initial values for the generation cycle authentication code. |
|||
* ECX = 0 |
|||
* The contents of the segment registers unchanged. |
|||
<lang Asm> .386 |
|||
.model flat |
|||
.code |
|||
_gost32 proc near32 |
|||
public _gost32 |
|||
; Внутренний цикл работы П/П |
|||
; 1. Начало цикла и сохранение старого N1 |
|||
iloop: mov EBP,EAX |
|||
; 2. Добавление к S ключа по модулю 2^32 |
|||
add EAX,[ESI] ; добавить ключ |
|||
add ESI,4 ; следующий эл. ключа |
|||
; 3. Поблочная замена в S с вращением на 8 бит влево |
|||
REPT 3 |
|||
xlat ; перекодировка байта |
|||
ror EAX,8 ; AL <- следующий байт |
|||
add EBX,100h; следующий узел замен |
|||
ENDM |
|||
xlat ; перекодировка байта |
|||
sub EBX,300h; BX -> 1-й узел замен |
|||
; 4. Доворот S на 3 бита влево |
|||
rol EAX,3 |
|||
; 5. Вычисление новых значений N1,N2 |
|||
xor EAX,EDX |
|||
mov EDX,EBP |
|||
; Завершение внутреннего цикла |
|||
loop iloop |
|||
ret |
|||
_gost32 endp |
|||
end |
|||
</lang> |
|||
=={{header|C}}== |
=={{header|C}}== |
Revision as of 17:48, 8 September 2012
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.
X86 Assembly
Parameter in the call:
- EAX - the youngest part of the transformed block (N1);
- EDX - leading part transformed block (N2);
- ESI - address of the first element of the key;
- EBX - table address changes;
- ECX - the number of major steps.
Output results:
- EDX = N1, EAX = N2 for cycles 32-З, 32-Р;
- EAX = N1, EDX = N2 for cycle 16-З.
Register Usage: all except EDI.
Notes:
- At the end of the run the registers as follows:
- EBX (table pointer changes) - the same as that in the early
- ESI (index key) - points to the first byte of the key - it's N * 4 larger than the initial values for the SI cycle reps H (for encryption cycles N = 32 => 4 * N = 128, for authentication code generation cycle N = 16 => 4 * N = 64), larger than the initial values for the generation cycle authentication code.
- ECX = 0
- The contents of the segment registers unchanged.
<lang Asm> .386
.model flat .code
_gost32 proc near32
public _gost32
- Внутренний цикл работы П/П
- 1. Начало цикла и сохранение старого N1
iloop: mov EBP,EAX
- 2. Добавление к S ключа по модулю 2^32
add EAX,[ESI] ; добавить ключ add ESI,4 ; следующий эл. ключа
- 3. Поблочная замена в S с вращением на 8 бит влево
REPT 3
xlat ; перекодировка байта ror EAX,8 ; AL <- следующий байт add EBX,100h; следующий узел замен
ENDM
xlat ; перекодировка байта sub EBX,300h; BX -> 1-й узел замен
- 4. Доворот S на 3 бита влево
rol EAX,3
- 5. Вычисление новых значений N1,N2
xor EAX,EDX mov EDX,EBP
- Завершение внутреннего цикла
loop iloop ret
_gost32 endp
end
</lang>
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>
C++
<lang Cpp>UINT_32 TGost::ROL(UINT_32 X, BYTE n) {
_asm{ mov eax, X mov cl, n rol eax, cl
mov X,eax
}
return UINT_32(X); }
UINT_64 TGost::SWAP32(UINT_32 N1, UINT_32 N2) {
UINT_64 N;
N = N1; N = (N<<32)|N2; return UINT_64(N); }
UINT_32 TGost::ReplaceBlock(UINT_32 x) {
register i; UINT_32 res = 0UL; for(i=7;i>=0;i--) { ui4_0 = x>>(i*4); ui4_0 = BS[ui4_0][i]; res = (res<<4)|ui4_0; } return res;
}
UINT_64 TGost::MainStep(UINT_64 N,UINT_32 X) {
UINT_32 N1,N2,S=0UL; N1=UINT_32(N); N2=N>>32; S = N1 + X % 0x4000000000000; S = ReplaceBlock(S); S = ROL(S,11); _asm{
mov eax,N2 xor S,eax
} N2 = N1; N1 = S; return SWAP32(N2,N1);
}</lang>
Variable "BS" is the replacement table.
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
Here the function "БеззнСлжПоМод32" sells unsigned add numbers modulo 232, "ИсклИЛИ" implements bitwise XOR of 32-bit variables, and "Замена" by replacing the specified 4-bit block.
ПЕР
Ключ: РЯД 8 ИЗ ЦЕЛ;
ТаблицаЗамен: РЯД 8, 16 ИЗ ЯЧЦЕЛ;
ЗАДАЧА БеззнСлжПоМод32(ч1, ч2: ЦЕЛ): ЦЕЛ;
ПЕР
память1, память2: ШИРЦЕЛ;
результат: ЦЕЛ;
УКАЗ
память1 := 0; ОБХОД.Образ(ОБХОД.ПолучитьАдрес(ч1), ОБХОД.ПолучитьАдрес(память1), 4);
память2 := 0; ОБХОД.Образ(ОБХОД.ПолучитьАдрес(ч2), ОБХОД.ПолучитьАдрес(память2), 4);
УВЕЛИЧИТЬ(память1, память2);
ОБХОД.Образ(ОБХОД.ПолучитьАдрес(память1), ОБХОД.ПолучитьАдрес(результат), 4);
ВОЗВРАТ результат
КОН БеззнСлжПоМод32;
ЗАДАЧА ИсклИЛИ(ч1, ч2: ЦЕЛ): ЦЕЛ;
УКАЗ
ВОЗВРАТ ОБХОД.Значение(ЦЕЛ, ОБХОД.Значение(МНОЖ, ч1) / ОБХОД.Значение(МНОЖ, ч2))
КОН ИсклИЛИ;
ЗАДАЧА Замена(стр: ЯЧЦЕЛ; яч: ОБХОД.Ячейка): ЯЧЦЕЛ;
ПЕР
п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: ШИРЦЕЛ; X: ЦЕЛ): ШИРЦЕЛ;
ПЕР
N1, N2, S: ЦЕЛ;
сч: ЯЧЦЕЛ;
ячейка: ЯЧЦЕЛ;
результат: ШИРЦЕЛ;
УКАЗ
ОБХОД.Образ(ОБХОД.ПолучитьАдрес(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);
ВОЗВРАТ результат
КОН ОсновнойШаг;