Autor teksta: Krunoslav Tomičić

Uvod

Crystals-Kyber

Kyber je kriptografski sustav razmjene ključeva i enkripcije koji se temelji na težini rješavanja
problema učenja s greškama (LWE) preko modul rešetki. Osnovna jednadžba glasi B = As + e    mod q
Finalist je NIST-ovog post-kvantnog kriptografskog natječaja.


Program

Uvod

Koristimo neslužbenu implementaciju koju se može preuzeti kao zip datoteku i koja sadrži izvorni kod algoritma. U sklopu projekta, u programskom jeziku Python, napravljeno je sučelje za demonstraciju rada Kyber-a.

Implementacija

Potrebno je raspakirati skinutu zip datoteku, zatim se pozicionirati u /pyky, te dodati datoteku: main.py

Demonstracija

Python program pokreće se iz direktorija u kojemu se nalazi datoteka main.py sljedećom naredbom:

pokretanje_python_porgrama
Slika 1: Pokretanje python programa

Otvara se prozor:

pocetni_zaslon
Slika 2: Početni zaslon

Pritiskom na dio prozora u kojemu piše "KEY ENCAPSULATION MECHANISM" otvara se sljedeći prozor:

digitalni_potpis
Slika 3: Enkapsulacija ključa

Pritiskom na gumb "Generiraj seed" generiramo seed koji se koristi za kreiranje privatnog i javnog ključa. Pritiskom na gumb "Generiraj par ključeva" generiramo privatni i javni ključ. Pritiskom na gumb "Enkapsuliraj" dobivamo šifru i zajedničku tajnu.

unos_poruke_i_generiranje_kljuceva
Slika 4: Generiranje seed-a, ključeva i enkapsulacija

Pritiskom na gumb "Dekapsuliraj - provjeri zajedničku tajnu" provjerava se je li šifra generirana iz javnog ključa valjana za zadani tajni ključ.

provejra_ispravnog_digitalnog_potpisa
Slika 5: Provjera ispravne enkapsulacije

Poruka o ispravnosti postupka enkapsulacije prikazuje se u doljnjem prozoru. Pritiskom na gumb olovčice u poljima "Javni ključ", "Privatni ključ" i "Seed" moguće je ručno promijeniti vrijednosti navedenih polja. Ukoliko tajni ključ ne odgovara javnom ključu, enkapsulacija će biti neispravna.

rucna_promjena_digitalnog_potpisa
Slika 6: Ručna promjena tajnog ključa
provjera_neispravnog_digitalnog_potpisa
Slika 7: Provjera neispravne enkapsulacije

Program se također sastoji i od enkripcije.

provjera_neispravnog_digitalnog_potpisa
Slika 8: Enkripcija

Pritiskom na gumb "Generiraj seed" generiramo seed koji se koristi za kreiranje privatnog i javnog ključa. Pritiskom na gumb "Generiraj par ključeva" generiramo privatni i javni ključ. Pritiskom na gumb "Kriptiraj" dobivamo šifru.

unos_poruke_i_generiranje_kljuceva
Slika 9: Generiranje seed-a, ključeva i enkripcija

Pritiskom na gumb "Dekriptiraj poruku" provodi se dekripcija šifre korištenjem tajnog ključa.

provejra_ispravnog_digitalnog_potpisa
Slika 10: Dekripcija poruke

Algoritam

Crystals-Kyber ostvaren je na nekoliko razina sigurnosti. Ovdje su navedeni odgovarajući setovi parametara.

Set parametara n k q η1 η2 (du, dv) δ
Kyber512 256 2 3329 3 2 (10, 4) 2-139
Kyber768 256 3 3329 2 2 (10, 4) 2-164
Kyber1024 256 4 3329 2 2 (11, 5) 2-174

Funkcije enkapsulacije

Generiranje ključeva

KYBER.CCAKEM.KeyGen()
Izlaz: Javni ključ pk - B (12 · k · n/8 + 32)
Izlaz: Tajni ključ sk - B (24 · k · n/8 + 96)

z ← B32
(pk, sk') := Kyber.CPAPKE.KeyGen()
sk := (sk' ‖ pk ‖ H(pk) ‖ z)
return (pk, sk)

Duljine uz definirane konstante (u bajtovima):
Javni ključ - pk: 800
Tajni ključ - sk: 1632

Enkapsulacija simetričnog ključa

Funkcija enkapsulacije ključa na ulazu uzima prethodno generirani javni ključ te pomoću njega vraća dva druga parametra. Šifru i zajedničku tajnu.
Zajednička tajna je u ovom slučaju vektor duljine 32 bajta i predstavlja generirani simetrični ključ
koji treba enkapsulirati u asimetričnom algoritmu. Šifra je enkapsulirani simetrični ključ.

KYBER.CCAKEM.Enc(pk)
Ulaz: Javni ključ pk - B (12 · k · n/8 + 32)
Izlaz: Šifra c - B (du · k · n/8 + dv · n/8)
Izlaz: Zajednička tajna K - B*

m ← B32
m ← H(m)
(K, r) := G(m ‖ H(pk))
c := Kyber.CPAPKE.Enc(pk, m, r)
K := KDF(K ‖ H(c))
return (c, K)

Duljine uz definirane konstante (u bajtovima):
Šifra - c: 768
Zajednička tajna - K: 32

Dekapsulacija simetričnog ključa

Funkcija dekapsulacije prima šifru te s pomoću tajnog ključa vraća dekapsuliranu zajedničku tajnu (ključ za simetričnu kriptografiju).

KYBER:CCAKEM:Dec(c, sk)
Ulaz: Šifra c - B (du · k · n/8 + dv · n/8)
Ulaz: Tajni ključ sk - B (24 · k · n/8 + 96)
Izlaz: Zajednička tajna K - B*

pk := sk + 12 · k · n/8
h := sk + 24 · k · n/8 + 32 ∈ B32
z := sk + 24 · k · n/8 + 64
m' := Kyber.CPAPKE.Dec(s, (u, v))
(K', r') := G(m' ‖ h)
c' := Kyber.CPAPKE.Enc(pk, m', r')
if c = c' then
return K := KDF(K' ‖ H(c))
else
return K := KDF(z ‖ H(c))
end if
return K

Duljine uz definirane konstante (u bajtovima):
Zajednička tajna - K: 32




Funkcije enkripcije

Generiranje ključeva

Funkcija generiranja ključeva vraća dva vektora različitih duljina.

KYBER.CPAPKE.KeyGen()
Izlaz: Tajni ključ sk - B (12 · k · n/8)
Izlaz: Javni ključ pk - B (12 · k · n/8 + 32)

d ← B32
(ρ, σ) := G(d)
N := 0
for i from 0 to k - 1 do  
  for j from 0 to k - 1 do
    Â[i][j] := Parse(XOF(ρ, j, i))
  end for
end for
for i from 0 to k - 1 do 
  s[i] := CBDη1(PRF(σ, N ))
  N := N + 1
end for
for i from 0 to k - 1 do  
  e[i] := CBDη1(PRF(σ, N ))
  N := N + 1
end for
ŝ := NTT(s)
ê := NTT(e)
t̂ := Â ◦ ŝ + ê
pk := (Encode12(t̂ mod+q)‖ρ) . pk := As + e
sk := Encode12(ŝ mod+q) . sk := s
return (pk , sk)
                  

Duljine uz definirane konstante (u bajtovima):
Javni ključ - pk: 768
Tajni ključ - sk: 800

Enkripcija poruke

Za enkripciju poruke koristi se javni ključ I “salt”, što je vektor 32 nasumično odabrana bajta.
Bitno je naglasiti da je ulazna poruka također 32 bajtni vektor te ukoliko želimo enkriptirati poruku proizvoljne duljine,
moramo obaviti dopunu do duljine djeljive s 32 te šifrirati koristeći neki od poznatih modova operacije u blok kodovima.

KYBER.CPAPKE.Enc(pk ,m , r)
Ulaz: Javni ključ pk - B (12 · k · n/8 + 32)
Ulaz: Poruka m - B 32
Ulaz: Salt r - B 32
Izlaz: Šifra c - B (du · k · n/8 + dv · n/8)

N := 0
t̂ := Decode12(pk )
ρ := pk + 12 · k · n/8
for i from 0 to k - 1 do 
  for j from 0 to k - 1 do 
    ÂT [i][j] := Parse(XOF(ρ, i, j))
  end for
end for
for i from 0 to k - 1 do  
  r[i] := CBDη1(PRF(r, N ))
  N := N + 1
end for
for i from 0 to k - 1 do  
  e1[i] := CBDη2 (PRF(r, N ))
  N := N + 1
end for
e2 := CBDη1(PRF(r, N )) 
r̂ := NTT(r)
u := NTT-1T ◦ r̂) + e1 
v := NTT-1(t̂T ◦ r̂) + e2 + Decompressq(Decode1(m), 1) 
c1 := Encodedu(Compressq(u, du))
c2 := Encodedv(Compressq(v, dv))
return c = (c1 ‖ c2)

Duljine uz definirane konstante (u bajtovima):
Šifra - c: 768

Dekripcija poruke

Funkcija dekapsulacije prima šifru te s pomoću tajnog ključa vraća dekapsuliranu zajedničku tajnu (ključ za simetričnu kriptografiju).

KYBER.CPAPKE.Dec(sk, c)
Ulaz: Tajni ključ sk - B (12 · k · n/8)
Ulaz: Šifra c - B (du · k · n/8 + dv · n/8)
Izlaz: Poruka m - B 32

u := Decompressq(Decodedu(c), du)
v := Decompressq(Decodedv(c + du · k · n/8), dv)
ŝ := Decode12(sk)
m := Encode1(Compressq(v - NTT-1T ◦ NTT(u)), 1))
return m

Duljine uz definirane konstante (u bajtovima):
Poruka - K: 32




Algoritam enkripcije

Generiranje ključa

alice_keygen

Alice generira matricu A dimenzija n x n nasumičnih koeficijenata,
te dva vektora, s dimenzije K i vektor e, vrlo malih koeficijenata.
Nakon toga računa vektor t također dimenzije K.
Objavljuje javni ključ (A,t) te za sebe ostavlja privatni ključ (s)



Enkripcija poruke

bob_encrypt

Bob generira nasumični vektor r duljine K te pomoću njega,
javnog ključa dobivenog od Alice, malih error-a e1 i e2 te same poruke m dobiva šifru (u, v).



Računanje v dijela

calculating v

U ovom koraku t se rastavlja na svoje dijelove A x s + e.
Množenjem svih komponenti s r dobivamo rAs + re.
Imajući na umu da su koeficijenti greški (e, e1, e2) izrazito mali, oni ne pridonose mnogo cjelini.
Onda je r x e vrlo mal i objedinjujemo ga s e2 te i dalje imamo vrlo neznatan vektor. (Na slici žuti bez naziva)
Ono što nam ostaje na kraju je rAs + greška + m



Računanje u x s dijela

calculating u

U se rastavlja na r x A + e1 te se oba dijela vektorski množe sa s.
U prethodnom koraku smo se vidi da je v jednako rAs + greška + m.
No u ovom koraku dobivamo da je vektorski umnožak u x s jedak rAs + e1s.
Možemo prepoznati jednak dio obje jednadže - rAs i znajući da je e1s također vrlo malih koeficijenata
govorimo kako je u x s aproksimativno jednako v - m!



Dekripcija poruke

decrypt

Nakon što su prethodni koraci uspješno obavljeni sama dekripcija poruke postaje vrlo jednostavna.
Oduzimanjem u x s od v. Uvrštavajući prethodno raspisane korake, poništavaju se izrazi rAs
i ostaje samo m + greška gdje je greška dovoljno mala da ne utječe na originalnu poruku.

Literatura