# Kuznyechik

Kuznyechik (en ruso: Кузнечик) es un cifrado por bloques simétrico. El cual tiene un tamaño de bloque de 128 bits y una longitud de clave de 256 bits. Está definido en el Estándar Nacional de la Federación Rusa GOST R 34.12-2015 in English y también en RFC 7801.
El nombre del cifrado se puede traducir del ruso. como saltamontes, sin embargo, El estándar dice explícitamente que el nombre en inglés para el cifrado es Kuznyechik . Los diseñadores afirman que al nombrar el código Kuznyechik ellos siguen la tendencia de los nombres de algoritmos difíciles de pronunciar. Esto debido a Rijndael y Keccak. También hay un rumor que el algoritmo fue llamado así por sus creadores: A.S.Kuzmin, A.A.Nechaev (Ruso: Кузьмин, Нечаев и Компания).
El Estándar GOST R 34.12-2015 define al nuevo algoritmo en adición al viejo GOST block cipher (Ahora llamado Magma) Uno y no declara obsoleto el antiguo cifrado.
Kuznyechik está basado en una Red de sustitución-permutación, A través de key schedule emplea una Red de Feistel.

## Designaciones

$\mathbb {F}$ — Cuerpo finito $GF(2^{8})$ $x^{8}+x^{7}+x^{6}+x+1$.
$Bin_{8}:\mathbb {Z} _{p}\rightarrow V_{8}$ — $\mathbb {Z} _{p}$ ($p=2^{8}$)
${Bin_{8}}^{-1}:V_{8}\rightarrow \mathbb {Z} _{p}$ — $Bin_{8}$.
$\delta :V_{8}\rightarrow \mathbb {F}$ — $\mathbb {F}$.
$\delta ^{-1}:\mathbb {F} \rightarrow V_{8}$ — $\delta$

## Descripción

Para cifrado, decifrado y generación de claves, las siguientes funciones:
$Add_{2}[k](a)=k\oplus a$, donde $k$, $a$ son cadenas binarias de la forma $a=a_{15}||$…$||a_{0}$ ($||$ es una cuerda concatenación).
$N(a)=S(a_{15})||$…$||S(a_{0}).~~N^{-1}(a)$ es una transformación invertida de $N(a)$.
$G(a)=\delta (a_{15},$…$,a_{0})||a_{15}||$…$||a_{1}.$
$G^{-1}(a)$ — transformación invertida de $G(a)$ , $G^{-1}(a)=a_{14}||a_{13}||$…$||a_{0}||\delta (a_{14},a_{13},$…$,a_{0},a_{15}).$
$H(a)=G^{16}(a)$, where $G^{16}$ — composición de transformaciones $G^{15}$ and $G$ etc.
$F[k](a_{1},a_{0})=(HNAdd_{2}[k](a_{1})\oplus a_{0},a_{1}).$

### La transformación no lineal

Transformación no lineal es dada por subtistuir S = Bin$_8$ S' Bin$_8$$^{−1}$.
Valores de la sustitución S' se dan como matriz S' = (S'(0), S'(1), …, S'(255)):
$S'=(252,238,221,17,207,110,49,22,251,196,250,218,35,197,4,77,233,$ $119,240,219,147,46,153,186,23,54,241,187,20,205,95,193,249,24,101,$ $90,226,92,239,33,129,28,60,66,139,1,142,79,5,132,2,174,227,106,143,$ $160,6,11,237,152,127,212,211,31,235,52,44,81,234,200,72,171,242,42,$ $104,162,253,58,206,204,181,112,14,86,8,12,118,18,191,114,19,71,156,$$$$183,93,135,21,161,150,41,16,123,154,199,243,145,120,111,157,158,178,$ $177,50,117,25,61,255,53,138,126,109,84,198,128,195,189,13,87,223,$ $245,36,169,62,168,67,201,215,121,214,246,124,34,185,3,224,15,236,$ $222,122,148,176,188,220,232,40,80,78,51,10,74,167,151,96,115,30,0,$ $98,68,26,184,56,130,100,159,38,65,173,69,70,146,39,94,85,47,140,163,$ $165,125,105,213,149,59,7,88,179,64,134,172,29,247,48,55,107,228,136,$ $217,231,137,225,27,131,73,76,63,248,254,141,83,170,144,202,216,133,$ $97,32,113,103,164,45,43,9,91,203,155,37,208,190,229,108,82,89,166,$ $116,210,230,244,180,192,209,102,175,194,57,75,99,182).$

### Transformación lineal

$\gamma$: $\gamma (a_{15},$…$,a_{0})=\delta ^{-1}~(148*\delta (a_{15})+32*\delta (a_{14})+133*\delta (a_{13})+16*\delta (a_{12})+$ $194*\delta (a_{11})+192*\delta (a_{10})+1*\delta (a_{9})+251*\delta (a_{8})+1*\delta (a_{7})+192*\delta (a_{6})+$ $194*\delta (a_{5})+16*\delta (a_{4})+133*\delta (a_{3})+32*\delta (a_{2})+148*\delta (a_{1})+1*\delta (a_{0})),$
Las operaciones de suma y multiplicación se realizan en el campo $\mathbb {F}$.

### Generación de clave

algoritmo de generación de claves utiliza constante iterativa $C_{i}=H(Bin_{128}(i))$, i=1,2,…32. Establece la clave compartida $K=k_{255}||$…$||k_{0}$.
Llaves iteradas
$K_{1}=k_{255}||$…$||k_{128}$
$K_{2}=k_{127}||$…$||k_{0}$
$(K_{2i+1},K_{2i+2})=F[C_{8(i-1)+8}]$…$F[C_{8(i-1)+1}](K_{2i+1},K_{2i}),i=1,2,3,4.$

### Algoritmo de cifrado

$E(a)=Add_{2}[K_{10}]HNAdd_{2}[K_{9}]$…$HNAdd_{2}[K_{3}]HNAdd_{2}[K_{1}](a),$ where a — 128-bit string.

### Algoritmo de descifrado

$D(a)=Add_{2}[K_{1}]H^{-1}N^{-1}Add_{2}[K_{2}]$…$H^{-1}N^{-1}Add_{2}[K_{9}]H^{-1}N^{-1}Add_{2}[K_{10}](a).$

## Adopción

VeraCrypt (un fork de TrueCrypt) incluye a Kuznyechik como uno de sus algoritmos de cifrado soportados.

## Código Fuente

https://web.archive.org/web/20160424051147/http://tc26.ru/standard/draft/PR_GOSTR-bch_v4.zip
https://web.archive.org/web/20180406230057/https://fossies.org/windows/misc/VeraCrypt_1.22_Source.zip/src/Crypto/kuznyechik.c (Enlace alternativo para el caso en el que el primer enlace no funcione.)