Parameters
Overview
VIA is not a single parameter set; it is a recipe for choosing one, valid only when it clears the security and correctness checks together (the Primer lays out that model). This page is the recipe itself: the knobs, why the two checks pull against each other, the descending modulus chain, and the value tables: the paper’s numbers alongside what the code sets. Where those values fail a check is the Gaps tab.
The short version of the divergence: inference the code faithfully ships the published paper, but the published paper's gadget bases were a draft the authors later corrected, and the published security level is higher than what reviewers measured on the authors' own implementation. So "matches the paper" and "is correct/secure as intended" are not the same statement here — see the Audit for the severity-ranked consequences.
The knobs
VIA is built on RLWE/MLWE, so its parameters are the usual lattice-encryption knobs plus a few PIR-specific ones. Grouped:
| Knob | What it is | Why it exists |
|---|---|---|
| Ring dimensions \(n_1 > n_2\ (> n_3)\) | polynomial degrees of the "big" ring, the "small" ring, and (VIA-B) the record ring. Powers of two for the NTT. | bigger \(n\) means more security and more packing capacity, at more compute; the descent \(n_1\!\to\!n_2\) shrinks the answer |
| Modulus chain \(q_1 > q_2 > q_3 > q_4 > p\) | a descending sequence of ciphertext moduli used at successive pipeline stages, down to the plaintext modulus \(p\) | mod-switching down a step scales noise and ciphertext size down together (see Modulus chain) |
| Plaintext modulus \(p\) | message levels per coefficient; sets the scaling \(\Delta = q/p\) | larger \(p\) packs more data per coefficient but shrinks the per-step budget \(\Delta/2\) |
| Distributions \(\chi_S,\ \chi_E\) | the secret-key and error distributions (std-dev \(\sigma\) or bound), chosen per ring | larger \(\sigma\) raises security but adds noise; the noise lemmas assume a specific key shape |
| Gadget \((B,\ \ell)\) per gate | base \(B\) and digit-count \(\ell\) of the gadget decomposition, chosen separately for DMux, CMux/CRot, ring-switch, and conversion | the dominant correctness lever (see Correctness budget): trades key size/speed against noise |
| Database shape \(I \times J\) (and batch \(T\)) | rows × columns of the DB grid; \(d=n_1/n_2\) records per cell; \(T\) batched queries in VIA-B | sets how many noisy terms get summed — so the budget depends on the database size |
The security ↔ correctness tension
This is the whole game: the levers point in opposite directions. Reading the table, "turn up" means increase that one knob holding the others fixed.
| Turn up… | Correctness (noise budget) | Security (lattice hardness) | Other cost |
|---|---|---|---|
| \(n\) — ring dimension | better (more headroom) | better (harder lattice) | more compute; must stay a power of two |
| \(q\) — modulus | better (bigger \(\Delta\)) | worse (LWE easier as \(\sigma/q\) shrinks) | bigger ciphertexts / more communication |
| \(\sigma\) — error / key std-dev | worse (more noise) | better (harder) | — |
| \(p\) — plaintext modulus | worse (\(\Delta=q/p\) shrinks) | — | but packs more data per coefficient |
| gadget base \(B\) | worse (more decomposition noise, \(\sim q^2/(12\,B^{2\ell})\)) | — | smaller / faster keys (fewer digits) |
| gadget length \(\ell\) | better (more digits → less noise) | — | bigger keys, slower |
| \(I,\ J\) — database size | worse (first-dim sum \(\sim I\,n_1\,p^2\); \(+\log I,+\log J\) gate levels) | — | — |
So "make decryption reliable" pulls toward big \(q\), small \(\sigma\), small gadget bases, many digits, small database; "make it secure" pulls toward big \(n\), big \(\sigma\), modest \(q\). Parameter selection is the joint optimization that clears both targets while keeping communication small. inference The reason VIA can do this with modest parameters at all is that its two signature tricks — the DMux tree for query expansion and the LWE→RLWE conversion with only \(O(n\log n)\) noise growth — keep noise growing logarithmically in the database size instead of linearly.
The modulus chain
VIA does not use a single modulus; it uses a descending chain \(q_1 > q_2 > q_3 > q_4 > p\), mod-switching down between stages. Mod-switching from \(q_i\) to \(q_{i+1}\) multiplies both the value and the noise by \(q_{i+1}/q_i\), and rewrites each coefficient into fewer bits. Two payoffs follow:
- Communication. The answer is squeezed to a small modulus before being sent, so each coefficient costs fewer bits: VIA's headline metric is response size.
- The budget travels with the modulus. The query rides at the big \(q_1\) (where the LWE→RLWE conversion needs room); the first-dimension sum happens at \(q_2\); response compression walks \(q_2\!\to\!q_3\!\to\!q_4\). The final decode happens at \(q_4\), where in VIA-C \(\Delta/2=(q_4/p)/2\) is only on the order of a hundred: a tiny budget that works precisely because the noise was scaled down the chain alongside the modulus.
inference The practical consequence: the final-ring budget is small and unforgiving, so the question "exactly which threshold does decode compare against?" — \(q_4/p\) vs \((q_3-q_4)/p\) — is not pedantic; it changes the certified margin by a large factor (see Correctness budget and Audit A5).
The parameter values
One structural fact first, because it shapes every table below:
code the repository has
no plain-VIA protocol preset: the wired
end-to-end presets are all VIA-C / VIA-B:
REALISTIC_PARAMS (paper-scale),
SECURE_PARAMS (the ≥120-bit set — see
Fix), and the VIA-B
REALISTIC_B_PARAMS. The plain-VIA numbers appear only
as paper::Via* moduli aliases used in low-level
NTT/RNS unit tests, never in a PIR pipeline. So in the "code"
column the VIA values are never exercised end-to-end and the live
numbers are VIA-C / VIA-B. Tables below show the
REALISTIC (paper-scale) instantiation,
\(n_1=2048,\ n_2=512\); the secure \(n_1=4096\) set is on the
Fix page.
Rings & modulus chain
| Quantity | VIA | VIA-C & VIA-B |
|---|---|---|
| \(n_1\) (big ring) | 2048 | 2048 |
| \(n_2\) (small ring) | 512 | 512 |
| \(n_3\) (record ring) | n/a | paper symbolic only (no value) · code 2 (VIA-B) |
| \(q_1\) (big-ring modulus) | \(268369921^2 \approx 2^{57}\) paper; two distinct primes \(268369921\cdot536608769\) code | \(137438822401\cdot274810798081 \approx 2^{75}\) (paper = code) |
| \(q_2\) | \(34359214081 \approx 2^{35}\) | \(17175674881 \approx 2^{34}\) |
| \(q_3\) (small-ring modulus) | \(2147352577 \approx 2^{31}\) | \(8380417 \approx 2^{23}\) |
| \(q_4\) (final modulus) | \(2^{15}=32768\) | \(2^{12}=4096\) |
| \(p\) (plaintext modulus) | 256 | 16 |
Source: paper Appendix B, p.22 (moduli) & §5.1, p.16 (dimensions); code basis.rs (q1 primes), modulus.rs (q2–q4, p), presets.rs. inference Caveats: the code's VIA-C moduli match the paper exactly; only plain-VIA's \(q_1\) diverges (square vs two primes). \(n_3\) is never given a number in the paper.
Distributions (secret key \(\chi_S\), error \(\chi_E\))
| Where | VIA (paper) | VIA-C & VIA-B (paper) | Code (all variants) |
|---|---|---|---|
| Big-ring secret \(\chi_{1,S}\) | uniform on \([-2,2]\) | Gaussian \(\sigma_{1,S}=32\) |
declares Gaussian with placeholder
\(\sigma=1.0\); all dead: every test
samples Ternary
|
| Big-ring error \(\chi_{1,E}\) | Gaussian \(\sigma_{1,E}=1\) | Gaussian \(\sigma_{1,E}=1024\) | |
| Small-ring \(\chi_{2,S}=\chi_{2,E}\) | Gaussian \(\sigma=4960\) | Gaussian \(\sigma=26\) |
Source: paper §5.1, p.16; code presets.rs:158-164, client.rs:93-105. inference Two traps here: the paper prints the small-ring \(\sigma\) under a typo'd \(\sigma_{1,E}\) subscript (it is \(\chi_2\)'s, not the big ring's); and the code's \(\sigma=1.0\) fields are never read: the actual key/error is ternary, so neither the paper's \(\sigma\) nor the preset's \(1.0\) is what runs (A4).
Gadget parameters
This is where "matches the paper" and "is correct as intended" come apart. The lengths \(\ell\) are unchanged across draft and erratum (so performance/key-size is identical); only the bases \(B\) moved, and the base is what governs the noise. VIA-C / VIA-B:
| Gate | \(\ell\) | Paper Table 6 base \(B\) (draft) | Authors' erratum base \(B\) | Code base \(B\) |
|---|---|---|---|---|
| Conversion key | 18 | 18 | 11 | 18 |
| DMux | 2 | 55879 | 18073 | 55879 |
| CMux / CRot | 2 | 81 | 307 | 81 |
| Ring-switching key | 8 | 8 | 4 | 8 |
Source: paper Table 6, p.23 (draft); Security review VIA authors' May-11 erratum ("Table 6 … were inadvertently left at draft values"), \(\log_2 P_{\text{fail}}\approx-43.4\) at 32 GiB with the corrected bases; code presets.rs:150,153,156 (unchanged at the audited commit: erratum not adopted). inference The code ships the draft bases, which the authors' own analysis does not certify to \(2^{-40}\); plain VIA's gadgets are a separate set (Table 5: DMux \(B{=}370758\), CMux \(B{=}24\), rs \(B{=}24\)) and are not implemented.
Database dimensions (paper Table 4, p.23)
| Database | VIA \((I,\ J)\) | VIA-C & VIA-B \((I,\ J)\) |
|---|---|---|
| 1 GB | \((2^{6},\ 2^{13})\) | \((2^{8},\ 2^{12})\) |
| 4 GB | \((2^{8},\ 2^{13})\) | \((2^{9},\ 2^{13})\) |
| 32 GB | \((2^{9},\ 2^{15})\) | \((2^{11},\ 2^{14})\) |
inference \(I\) (rows, the first-dimension sum) and \(J\) (columns, the CMux tree) are the noise drivers — bigger means more accumulated error — so the parameter set is only valid for a given database size. Security review The authors note the code does not auto-configure \(\log I,\log J\); they must be set by hand to match the target size.