## TODOs - [ ] trait for `Ring`, `PolynomialRing`, `Module` - [ ] implement cyclotomic polynomial and rings, and arithemetics - [ ] trait for `Sampler` - [ ] implement uniform sampler - [ ] implement CBD Sampler - [ ] (De)compression - [ ] (De)serialization - [ ] implement NTT - [ ] CPA-PKE.KeyGen, Enc, Dec - [ ] CCA-KEM.KeyGen, Encapsulate, Decapsulate (use RustCrypto's [trait](https://github.com/RustCrypto/traits/tree/master/kem)) - [ ] End-to-end Testvectors - [ ] Benchmarks & Profiling ## System parameters - Degree of ring (over $\mathbb{Z}$): $n=256$ - Rank of Mod-LWE: $k$ - number of samples in RLWE $m=k$, thus ignored - Modulus for quotient ring: $q=3329$ - Error distribution: $\eta_1, \eta_2$ - central binomial distribution $B_\eta$ (see definition [below](#CBD-Sampler)) - only for Kyber512, $\eta_1 > \eta_2$, for the rest, $\eta_1=\eta_2$ - secret $s$ also drawn from this distribution, see rationale in the slide - Ciphertext round-off bits: $d_u, d_v$ - $ct.u$ truncates to $\mathbb{Z}_{2^{d_u}}$, $ct.v$ truncates to $\mathbb{Z}_{2^{d_v}}$ - "truncate" means dropping the LSB of each coeff (originally $\in \mathbb{Z}_q$) ## Building blocks ### Algebriac Objects Ring $R$, Quotient Ring $R_q$, Module $M=R_q^k$, Matrix ($R_q^{k\times m}$) and matrix multiplication. Polynomial ring with polynomial modulo operation. ### NTT See Kyber spec. ### Uniform Sampler Idea behind $\mathsf{Parse}()$ is simple: since $2^{11}<q<2^{12}$, let's use every 12 bits from a uniform random bytes string to generate a coeff in the NTT form of $R_q$. Furthermore, when the 12-bit value $>q$, reject it. Every 2 12-bit = 3 bytes, thus every 3 bytes can product at most 2 $\hat{R}_q$ elements subject the sample rejection. ### CBD Sampler To sample a value from $B_\eta$: Sample $(a_1,\ldots,a_\eta, b_1,\ldots,b_\eta)\leftarrow \{0,1\}^{2\eta}$, outputs $\sum_{i=[\eta]}{a_i-b_i}$. To sample a $R_q$, just sample each coeff from $B_\eta$. ### (De)Compression - Rounding/Discretization: $\lceil \cdot\rfloor: \mathbb{Q}\rightarrow \mathbb{Z}$ - Compress: $\mathsf{Compress}_q(x,d)= \lceil (2^d/q)\cdot x\rfloor\mod{2^d}$ - for $x\in\mathbb{Z}_q$ - for $x\in R_q$ (coeff-wise) - Decompress: $\mathsf{Decompress}_q(x,d)= \lceil (q/2^d)\cdot x\rfloor$ - for $x\in\mathbb{Z}_q$ - for $x\in R_q$ (coeff-wise) ### (De)Serialization Namely Encoding/Decoding in Kyber Spec. - serde for ring element: $\mathsf{Decode}_{12}(pk\in \mathcal{B}^{32\times 12})\rightarrow R_q$ - serde for message: $\mathsf{Decode}_{1}(msg\in \{0,1\}^{32})\rightarrow R_2 \subseteq R_q$ ### Symmetric Primitives All available in RustCryto | | FLPS-202 | 90s variant | | --- | --- | --- | | PRF | SHAKE-256 | AES-256-CTR | | XOF | SHAKE-128 | AES-256-CTR | | KDF | SHAKE-256 | SHA-256 | | Hash.H | SHA3-256 | SHA-256 | | Hash.G | SHA3-512 | SHA-512 | ## CPA-PKE + FO-derived KEM See Algorithm 4~9 in Kyber's spec. ## References - Kyber [spec v3.02](https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf) - "A Gentle Intro to Kyber" ([slide](https://drive.google.com/file/d/1FyX4kJ9WWuSOOmJDoApvwa87GO4wY0kA/view?usp=sharing))