Argon2

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

Argon2 este o derivare a unei chei criptografice care a fost selectată ca câștigătoare a concursului Hashing Password în iulie 2015 [1] [2] A fost proiectat de Alex Biryukov , Daniel Dinu și Dmitry Khovratovich de la Universitatea din Luxemburg . [3] Argon2 a fost lansat sub licența Creative Commons CC0 (adică domeniu public ) și furnizat în 3 versiuni diferite:

  • Argon2d
  • Argon2i
  • Argon2id

Algoritm

 Funcția Argon2
   Intrări:
      parola ( P ): octeți (0..2 32 -1) Parolă (sau mesaj) care trebuie hashată
      sare ( S ): octeți (8..2 32 -1) sare (16 octeți recomandați pentru hash-ul parolei)
      paralelism ( p ): Număr (1..2 24 -1) Grad de paralelism (adică numărul de fire)
      tagLength ( T ): Number (4..2 32 -1) Număr dorit de octeți returnați
      memorySizeKB ( m ): Number (8p..2 32 -1) Cantitatea de memorie (în kibibiți) de utilizat
      iterații ( t ): Număr (1..2 32 -1) Număr de iterații de efectuat
      versiunea ( v ): Număr (0x13) Versiunea curentă este 0x13 (19 zecimale)
      cheie ( K ): octeți (0..2 32 -1) Cheie opțională (Errata: PDF spune 0..32 octeți, RFC spune 0..2 32 octeți)
      associatedData ( X ): octeți (0..2 32 -1) Date suplimentare arbitrare opționale
      hashType ( y ): Number (0 = Argon2d, 1 = Argon2i, 2 = Argon2id)
   Ieșire:
      tag: Bytes (tagLength) Octetii generați rezultați, tagLength bytes lung

   Generați blocul inițial de 64 de octeți H 0 .
   Toți parametrii de intrare sunt concatenați și introduși ca o sursă de entropie suplimentară.
   Errata: RFC spune că H 0 are 64 de biți; PDF spune că H 0 are 64 de octeți.
   Errata: RFC spune că Hash este H ^, PDF-ul spune că este ℋ (dar nu documentează ce este ℋ). Este de fapt Blake2b.
   Elementele cu lungime variabilă sunt pregătite cu lungimea lor ca numere întregi de 32 de biți.
   buffer ← paralelism ∥ tagLength ∥ memorySizeKB ∥ iterații ∥ version ∥ hashType
         ∥ Lungime (parolă) ∥ Parolă
         ∥ Lungime (sare) ∥ sare
         ∥ Lungime (tasta) ∥ tasta
         ∥ Lungime (asociateDate) ∥ asociateDate
   H 0 ← Blake2b (tampon, 64) // mărimea hash implicită a lui Blake2b este de 64 de octeți

   Calculați numărul de blocuri de 1 KB rotunjind în jos memoria SizeKB la cel mai apropiat multiplu de 4 * kilobyți de paralelism
   blockCount ← Etaj (memorySizeKB, paralelism 4 *)

   Alocați o matrice bidimensională de 1 blocuri KiB (paralelism rânduri x columnCount coloane)
   columnCount ← blockCount / parallelism; // În RFC, columnCount este denumit q

   Calculați primul și al doilea bloc (adică coloana zero și una) din fiecare bandă (adică rând)
   pentru i ← 0 la paralelism-1 faceți pentru fiecare rând
      B i [0] ← Hash (H 0 ∥ 0 ∥ i, 1024) // Generați un rezumat de 1024 octeți
      B i [1] ← Hash (H 0 ∥ 1 ∥ i, 1024) // Generați un rezumat de 1024 octeți

   Calculați coloanele rămase ale fiecărei benzi
   pentru i ← 0 la paralelism-1 do // pentru fiecare rând
      pentru j ← 2 la columnCount-1 do // pentru fiecare coloană ulterioară
         // indexurile i și j depind dacă este vorba de Argon2i, Argon2d sau Argon2id (Vezi secțiunea 3.4)
         i ′, j ′ ← GetBlockIndexes (i, j)
         B i [j] = G (B i [j-1], B i ′ [j ′])

   Trece mai departe când iterațiile> 1
   pentru nIteration ← 2 iterații face
      pentru i ← 0 la paralelism-1 faceți pentru fiecare rând
        pentru j ← 2 la columnCount-1 do // pentru fiecare coloană ulterioară
           // indexurile i și j depind dacă este vorba de Argon2i, Argon2d sau Argon2id (Vezi secțiunea 3.4)
           i ′, j ′ ← GetBlockIndexes (i, j)
           B i [0] = G (B i [columnCount-1], B i ′ [j ′])
           B i [j] = G (B i [j-1], B i ′ [j ′])

   Calculați blocul final C ca XOR al ultimei coloane a fiecărui rând
   C ← B 0 [columnCount-1]
   pentru i ← 1 la paralelism-1 do
      C ← C xor B i [columnCount-1]

   Calculați eticheta de ieșire
   returnează Hash (C, tagLength)

Funcție hash de lungime variabilă

Argon2 folosește o funcție hash capabilă să producă digestii de până la 2 32 de octeți. Această funcție hash este construită intern pe Blake2 .

 Funcția Hash (mesaj, digestSize)
   Intrări:
      mesaj: octeți (0..2 32 -1) Mesaj care trebuie hash
      digestSize: Număr întreg (1..2 32 ) Numărul dorit de octeți care trebuie returnat
   Ieșire:
      digest: Bytes (digestSize) Octetii generați rezultați, digestSize bytes lung

   Hash este o funcție hash cu lungime variabilă, construită folosind Blake2b, capabilă să genereze
   digeră până la 2 32 de octeți.

   Dacă dimensiunea solicitată este de 64 de octeți sau mai mică, vom folosi direct Blake2b
   if (digestSize <= 64) atunci
      returnează Blake2b (digestSize ∥ mesaj, digestSize) // concatenează 32-bit endian digestSize mic cu octeții mesajului

   Pentru hashurile dorite peste 64 de octeți (de exemplu, 1024 octeți pentru blocurile Argon2),
   folosim Blake2b pentru a genera de două ori numărul de blocuri necesare pe 64 de octeți,
   și apoi utilizați doar 32 de octeți din fiecare bloc

   Calculați numărul de blocuri întregi (știind că vom folosi doar 32 de octeți din fiecare)
   r ← Plafon (digestSize / 32) -1;

   Generați r blocuri întregi.
   Blocul inițial este generat din mesaj
   V 1 ← Blake2b (mesaj Dimension ∥, 64);
   Blocurile ulterioare sunt generate din blocurile anterioare
   pentru i ← 2 to r do
      V i ← Blake2b (V i-1 , 64)
   Generați blocul final (posibil parțial)
   partialBytesNeeded ← digestSize - 32 * r;
   V r + 1 ← Blake2b (V r , partialBytesNeeded)

   Concatenează primii 32 de octeți ai fiecărui bloc V i
   (cu excepția ultimului bloc posibil parțial, pe care îl luăm în întregime)
   Fie A i să reprezinte cei 32 de octeți inferiori ai blocului V i
   retur A 1 ∥ A 2 ∥ ... ∥ A r ∥ V r + 1

Notă

linkuri externe