Argon2

El texto que sigue es una traducción defectuosa. Si quieres colaborar con Wikipedia, busca el artículo original y mejora esta traducción.

Copia y pega el siguiente código en la página de discusión del autor de este artículo: `{{subst:Aviso mal traducido|Argon2}} ~~~~`

|

Argon2 es una función de derivación de clave que fue seleccionada como la ganadora del concurso de comprobación de contraseñas de 2015.[1]​[2]​ Fue diseñada por Alex Biryukov, Daniel Dinu, y Dmitry Khovratovich de la Universidad de Luxemburgo.[3]​ La implementación de referencia de Argon2 se publica bajo una licencia Creative Commons CC0 (es decir, de dominio público) o la Apache License 2.0, y proporciona tres versiones relacionadas:

* Argon2d maximiza la resistencia a los ataques de cracking por GPU. Accede al array en memoria en un orden dependiente de la contraseña, lo que reduce la posibilidad de ataques de compensación tiempo-memoria (TMTO), pero introduce posibles ataques de canal lateral.
* Argon2i está optimizado para resistir ataques de canal lateral. Accede al array de memoria en un orden independiente de la contraseña.
* Argon2id es una versión híbrida. Sigue el enfoque de Argon2i en la primera mitad del recorrido de la memoria y el enfoque de Argon2d en los recorridos posteriores. El RFC 9106 recomienda usar Argon2id si no conoces la diferencia entre los tipos o consideras los ataques de canal lateral como una amenaza viable.[4]​

Los tres modos permiten la especificación de tres parámetros que controlan:

* Tiempo de ejecución
* Memoria requerida
* Grado de paralelismo

## Criptoanálisis

[editar]

Aunque no existe un criptoanálisis público aplicable a Argon2d, hay dos ataques publicados contra la función Argon2i. El primer ataque es aplicable solo a la versión antigua de Argon2i, mientras que el segundo se ha extendido a la versión más reciente (1.3).[5]​

El primer ataque muestra que es posible calcular una función Argon2i de una pasada utilizando entre una cuarta y una quinta parte del espacio deseado sin penalización de tiempo, y calcular una Argon2i de múltiples pasadas utilizando solo N/e (≈ N/2.72) de espacio sin penalización de tiempo.[6]​ Según los autores de Argon2, este vector de ataque fue solucionado en la versión 1.3.[7]​

El segundo ataque muestra que Argon2i puede ser computado por un algoritmo que tiene complejidad O(n7/4 log(n)) para todas las opciones de parámetros σ (costo de espacio), τ (costo de tiempo), y cantidad hilos de tal manera que n=σ∗τ.[8]​ Los autores de Argon2 afirman que este ataque no es eficiente si se usa Argon2i con tres o más pasadas.[7]​ Sin embargo, Joël Alwen y Jeremiah Blocki mejoraron el ataque y demostraron que, para que el ataque falle, Argon2i v1.3 necesita más de 10 pasadas sobre la memoria.[5]​

Para abordar estas preocupaciones, el RFC 9106 recomienda usar Argon2id para mitigar en gran medida tales ataques.[9]​

## Algoritmo

[editar]

Function Argon2
Inputs:
password (P):       Bytes (0..232-1)    Contraseña (o mensaje) a ser procesado
salt (S):           Bytes (8..232-1)    Salida (16 bytes recomendados para la contraseña encriptada)
parallelism (p):    Number (1..224-1)   Grado de paralelismo (i.e. número de threads)
tagLength (T):      Number (4..232-1)   Número deseado de bytes devueltos
memorySizeKB (m):   Number (8p..232-1)  Cantidad de memoria (en kibibytes) para usar
iterations (t):     Number (1..232-1)   Número de iteraciones a realizar
version (v):        Number (0x13)       La versión actual es 0x13 (19 decimal)
key (K):            Bytes (0..232-1)    Llave opcional (Errata: PDF says 0..32 bytes, RFC says 0..232 bytes)
associatedData (X): Bytes (0..232-1)    Datos adicionales arbitrarios opcionales
hashType (y):       Number (0=Argon2d, 1=Argon2i, 2=Argon2id)
Output:
tag:                Bytes (tagLength)   Los bytes generados resultantes, tagLength bytes long

Genera el bloque inicial de 64 bytes H0. Todos los parámetros de entrada se concatenan y se introducen como fuente de entropía adicional. Erratas: RFC dice que H0 es de 64 bits; PDF dice que H0 es de 64 bytes.
Errata: RFC dice que el Hash es H^, el PDF dice que es ℋ (pero no documenta lo que es ℋ). En realidad es Blake2b.
Los artículos de longitud variable se preparan con su longitud como números enteros de 32 bits.
buffer ← parallelism ∥ tagLength ∥ memorySizeKB ∥ iterations ∥ version ∥ hashType
∥ Length(password)       ∥ Password
∥ Length(salt)           ∥ salt
∥ Length(key)            ∥ key
∥ Length(associatedData) ∥ associatedData
H0 ← Blake2b(buffer, 64) // El tamaño de hash por defecto de Blake2b es de 64 bytes

Calcula el número de bloques de 1 KB redondeando hacia abajo (memorySizeKB) al múltiplo más cercano de 4*parallelism kibibytes
blockCount ← Floor(memorySizeKB, 4*parallelism)

Asignar una matriz bidimensional de bloques de 1 KiB (filas de parallelism x columnCount)
columnCount ← blockCount / parallelism;   //En la RFC, columnCount se denomina q

Computa el primer y segundo bloque (es decir, la columna cero y una ) de cada carril (es decir, la fila)
for i ← 0 to parallelism-1 do para cada fila
Bi[0] ← Hash(H0 ∥ 0 ∥ i, 1024) // Genera 1024-byte digest
Bi[1] ← Hash(H0 ∥ 1 ∥ i, 1024) // Genera 1024-byte digest

Computa las columnas restantes de cada carril
for i ← 0 to parallelism-1 do // para cada fila
for j ← 2 to columnCount-1 do // para cada columna subsiguiente
//Los índices "i" y "j" dependen de si se trata de Argon2i, Argon2d o Argon2id (véase la sección 3.4)
i′, j′ ← GetBlockIndexes(i, j)  //la función GetBlockIndexes no está definida
Bi[j] = G(Bi[j-1], Bi′[j′]) // la función G hash no está definida

Further passes when iterations > 1
for nIteration ← 2 to iterations do
for i ← 0 to parallelism-1 do para cada fila
for j ← 0 to columnCount-1 do // para cada columna subsiguiente
//Los índices "i" y "j" dependen de si se trata de Argon2i, Argon2d o Argon2id (véase la sección 3.4)
i′, j′ ← GetBlockIndexes(i, j)
if j == 0 then
Bi[0] = Bi[0] xor G(Bi[columnCount-1], Bi′[j′])
else
Bi[j] = Bi[j] xor G(Bi[j-1], Bi′[j′])

Calcula el bloque final C como el XOR de la última columna de cada fila
C ← B0[columnCount-1]
for i ← 1 to parallelism-1 do
C ← C xor Bi[columnCount-1]

Calcular la etiqueta de salida
return Hash(C, tagLength)

### Función hash de longitud-variable

[editar]

Argón2 hace uso de una función hash capaz de producir digests de hasta 232 bytes de largo. Esta función hash esta construida internamente construida sobre Blake2.

Function Hash(message, digestSize)
Inputs:
message:         Bytes (0..232-1)     Mensaje a ser procesado
digestSize:      Integer (1..232)     Número deseado de bytes a devolver
Output:
digest:          Bytes (digestSize)   Los bytes generados resultantes, digestSize de los bytes de largo

El hash es una función de longitud variable, construida usando Blake2b, capaz de generar digests de hasta 232 bytes.

Si el digestSize solicitada es de 64 bytes o menos, entonces usamos Blake2b directamente
if (digestSize <= 64) then
return Blake2b(digestSize ∥ message, digestSize) //concatenar 32-bit little endian digestSize con los bytes del mensaje

Para los hashes deseados de más de 64 bytes (por ejemplo, 1024 bytes para los bloques de Argon2), utilizamos Blake2b para generar el doble del número de bloques de 64 bytes necesarios, y luego sólo utilizamos 32 bytes de cada bloque

Calcula el número de bloques enteros (sabiendo que sólo vamos a usar 32 bytes de cada uno)
r ← Ceil(digestSize/32)-1;

Genera r bloques.
Bloque inicial generado desde el mensaje
V1 ← Blake2b(digestSize ∥ message, 64);
Los bloques subsiguientes se generan a partir de los bloques anteriores
for i ← 2 to r do
Vi ← Blake2b(Vi-1, 64)
Genera el bloque final (posiblemente parcial)
partialBytesNeeded ← digestSize – 32*r;
Vr+1 ← Blake2b(Vr, partialBytesNeeded)

Concatena los primeros 32 bytes de cada bloque Vi
(excepto el posible último bloque parcial, del que toma todo)
Que Ai represente los 32-bytes inferiores del bloque Vi
return A1 ∥ A2 ∥ ... ∥ Ar ∥ Vr+1

## Referencias

[editar]

1. ↑ "Password Hashing Competition"
2. ↑ Jos Wetzels (8 de febrero de 2016). Open Sesame: The Password Hashing Competition and Argon2.
3. ↑ Argon2: the memory-hard function for password hashing and other applications, Alex Biryukov, et al, October 1, 2015
4. ↑ Biryukov, Alex; Dinu, Daniel; Khovratovich, Dmitry; Josefsson, Simon (2021-09). Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications (RFC 9106). Internet Engineering Task Force. Consultado el 10 de septiembre de 2024.
5. ↑ a b Joël Alwen, Jeremiah Blocki (5 de agosto de 2016). Towards Practical Attacks on Argon2i and Balloon Hashing.
6. ↑ Henry Corrigan-Gibbs, Dan Boneh, Stuart Schechter (14 de enero de 2016). Balloon Hashing: Provably Space-Hard Hash Functions with Data-Independent Access Patterns.
7. ↑ a b «[Cfrg] Argon2 v.1.3». www.ietf.org. Consultado el 30 de octubre de 2016.
8. ↑ Joel Alwen, Jeremiah Blocki (19 de febrero de 2016). Efficiently Computing Data-Independent Memory-Hard Functions.
9. ↑ Biryukov, Alex; Dinu, Daniel; Khovratovich, Dmitry; Josefsson, Simon (2021-09). Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications (RFC 9106). Internet Engineering Task Force. Consultado el 10 de septiembre de 2024.

## Enlaces externos

[editar]

* Argón2 source code repository on Github
* Argón2 specification
* Password Hashing Competition
* Uni.Lu Argon2 Page
* Balloon Hashing: A Memory-Hard Function Providing Provable Protection Against Sequential Attacks

Control de autoridades|

* Proyectos Wikimedia
* Datos: Q21995362

|

* Datos: Q21995362