Skip to main content

Choosing parameters

A pipeline's homomorphic parameters are defined in HomParams. Four fields need an explicit choice on almost every pipeline: full_q_list_precision, n, pt_scale, and num_special_primes. The rest are covered at the end of this page.

Everything here builds on two facts from earlier in this section: multiplying grows a ciphertext's scale, and bringing scale back down spends a level from the modulus chain. If either of those is unfamiliar, start with Ciphertext state and Level budget, then return here to pick values.

Primary parameters

These depend on your model, packing, security target, and key-switching setup.
full_q_list_precisiontuple[tuple[int, ...], ...]modulus chain precision

Bit precision of each RNS prime in the modulus chain. Write it as a tuple of tuples, for example ((61,), (61,)) for two levels at 61 bits each. Each inner tuple corresponds to one level (a row in RNS form). The full row-and-column structure is covered on Level budget.

Set the number of levels from the multiplicative depth of your pipeline: use the minimum number of levels that covers the deepest path. Extra levels do not make the computation more accurate; they enlarge the total modulus, which hurts security and performance.
LongerMore multiplicative depth, but larger ciphertexts, slower evaluation, and a larger total modulus that needs a larger n to stay secure.
MinimumOne level per multiplication on the deepest path. Below that, the pipeline will not compile.
Need more depth?If a longer chain would hurt security or performance too much, use Bootstrap to refresh levels mid-pipeline instead of lengthening the chain.
nint (power of two)ring dimension

Ring dimension. A single ciphertext packs n / 2 slots, and together with the total modulus (and secret-key Hamming weight) it sets the pipeline's security parameter. For most large enough pipelines, n = 2**16 is the usual starting point when you need about 128-bit security; smaller powers of two can work for shallow pipelines if an estimator still reports enough security.

Two things push n up. Security depends on the size of n relative to the total modulus of the chain, so a larger total modulus needs a larger n to stay secure. Slot capacity also matters: each ciphertext holds n / 2 slots, but a larger input does not always require a larger n; you can batch across multiple ciphertexts at a smaller secure n, which is often faster overall. Pick the smallest n that stays secure for your chain.
LargerMore slots per ciphertext and more security headroom, but every operation runs slower. Prefer the smallest secure value.
Driven byTotal modulus size of the chain you chose above, and how you pack inputs across ciphertexts. A larger modulus raises the n you need for security.
pt_scaleint (power of two)plaintext encryption scale

Plaintext encryption scale. In CKKS, encryption has the form ct = a·sk + pt_scale·m + e. It sets the starting error-to-plaintext ratio for the encoded message, and it is the starting scale carried on each ciphertext (Ciphertext state).

A higher pt_scale gives more initial accuracy headroom for deeper pipelines, because the signal-to-error ratio of the underlying plaintext drops as operations accumulate. Two scale rules matter in practice: after a mod-switch that drops a prime of size B, scale becomes A / B; after multiplying two ciphertexts at scales A and B, the result is at A * B. Raising pt_scale does not by itself force a longer chain, but you still need primes that can hold the scales your pipeline produces, and the resulting total modulus must stay secure for your n.
HigherMore initial accuracy headroom, useful for larger pipelines. Keep the total modulus secure for your chosen n.
MinimumIn this implementation, pt_scale must be at least 2**30. Common working values are in the 2**30 to 2**50 range.
num_special_primesinthybrid key-switching

Number of special primes used during hybrid key switching. Almost every pipeline needs an explicit choice here, even though it is not part of the modulus chain itself.

Default key switching is hybrid GHS (decomposition_type=DecompositionType.HYBRID). Each special prime is 61 bits. A larger value lowers dnum, which shrinks the digit dimension of auxiliary keys (rotation and square keys) and speeds digit decomposition during key switching. A smaller value reduces the number of limbs on those keys and speeds the modDown step: a memory tradeoff. The best value for a pipeline depends on its size; find it by trying a few candidates.
LargerSmaller dnum, smaller digit dimension on auxiliary keys, faster digit decomposition.
SmallerFewer limbs on auxiliary keys (less memory), faster modDown during key switching.
If using BVWhen decomposition_type=DecompositionType.BV, set bv_gadget_bits instead; see Advanced parameters.

Pick them in this order

The fields are related. Work in this order so each choice has the inputs it needs.
01
full_q_list_precisionmodulus chain precision
Read the multiplicative depth off your pipeline (count it, or inspect levels in the debugger). Set the number of levels to that depth. A few operators let you trade levels for rotations and key size (level collapse); count depth at the stage_sizes setting you plan to use. Settle the chain first.
02
nring dimension
Take the smallest power of two that stays secure for the total modulus of the chain you just set (see Security below). Pack inputs into n / 2 slots per ciphertext; if needed, batch across multiple ciphertexts instead of raising n.
03
pt_scaleplaintext encryption scale
Set the accuracy headroom you need, at least 2**30. Remember that mod-switch divides scale by the dropped prime and multiplication multiplies scales. Tune upward if results drift.
04
num_special_primeshybrid key-switching
Choose a value for hybrid key switching, then try nearby values if auxiliary-key size or key-switch time dominates. If you switch to DecompositionType.BV, configure bv_gadget_bits instead.

Security

There is no built-in security parameter. Nothing in HomParams sets or checks a security level for you. Security is a property of the values you chose, and confirming it is your responsibility before deploying.

A pipeline's security parameter is a function of n, the total modulus of the chain, and the secret-key Hamming weight sk_hw. A larger total modulus needs a larger n (or a different sk_hw) to stay secure. The framework validates structural constraints (power-of-two n, prime bit ranges) but does not compute a bit-security estimate.
Once you have a candidate parameter set, confirm it externally with a lattice estimator such as the lattice-estimator (inputs typically include n, the total modulus size, and the error distribution), or use your own in-house estimation. We do not ship a calculator.
Every level you save is also a security win.

Because total modulus size feeds the security requirement, every level you save through careful depth counting is not just speed. A shorter chain lets you hold the same security at a smaller n, which is faster everywhere.

A starter set

There is no universal default: the right values depend on the pipeline. This set runs the digit recognizer from the example and is a fair starting point for a small, shallow model.
params.pyPYTHON · STARTER
from lattica_build.params import DecompositionType, HomParams

params = HomParams(
    full_q_list_precision=((61,), (45,)),
    n=2 ** 8,
    pt_scale=2 ** 20,
    decomposition_type=DecompositionType.BV,
)
Copy it, deploy, and adjust. If your model is deeper, add levels to the chain. If results lose precision, raise pt_scale. If key size or key-switch time dominates, try nearby num_special_primes values.

Advanced parameters

The remaining fields of HomParams. Most pipelines leave these at their defaults until a specific need appears.
ParameterTypeWhat it is and when to change it
err_stdfloatStandard deviation of the encryption error distribution. Keep the default 3.19: smaller values make the pipeline susceptible to attacks independently of n and Q; larger values reduce accuracy. Public estimators often assume 3.19 as an input.
sk_hwintHamming weight of the secret key. 0 (the default) gives a uniform ternary key, each coefficient uniform in −1, 0, 1. A value above 0 forces exactly that many nonzero coefficients: a sparse key, which reduces noise growth and can speed evaluation. A sparse key changes the security parameter, so any nonzero value must go into your external security estimate along with n and the total modulus precision.
decomposition_typeDecompositionTypeKey-switching decomposition strategy. Default is HYBRID. See Decomposition types below.
bv_gadget_bitsintRequired when decomposition_type=DecompositionType.BV: bit size of each digit in the gadget decomposition of auxiliary keys. Larger values mean a smaller key at the cost of more key-switch noise. Default is 4; must be a positive integer under BV.
bootstrapping_variantslim | realWhen the pipeline includes Bootstrap or HomRingSwitch, which bootstrap variant the pipeline uses (REAL or SLIM). See Bootstrap.
num_init_rowsint | NoneHow many rows of q_list form the initial modulus of the input ciphertext. Default None encrypts under the full pipeline q_list. Valid values are from 1 (first prime only) through the number of rows (same as None). When the pipeline includes Bootstrap or HomRingSwitch, the pipeline also has an extra prime q0 not listed in q_list, and num_init_rows=0 encrypts under q0 alone.
The compiler infers bootstrapping from the pipeline: if you include Bootstrap or HomRingSwitch, it is enabled automatically. Do not pass a bootstrapping flag on HomParams.

Decomposition types

decomposition_type controls how key-switching decomposes ciphertexts. With the default HYBRID, tune num_special_primes; with BV, set bv_gadget_bits. These choices affect key size, noise, and key-switch cost; they do not change your pipeline graph, shapes, or level budget.
HYBRIDdefault
Hybrid GHS key switching. Uses special primes for the modDown step; tune them with num_special_primes. Usually more accurate than standard gadget decomposition, and the usual choice for pipelines.
BVgadget
Standard gadget decomposition. Set bv_gadget_bits to the bit size of each digit. Usually builds a larger auxiliary key when bv_gadget_bits is small, and is noisier than hybrid. Skips the modDown step during key switching, at the cost of a heavier digit-decomposition step.
If key size or key-generation time becomes a problem for your deployment, this is the knob; otherwise leave hybrid at the num_special_primes you chose above.

Next

You now have what you need to set parameters: depth from Level budget, values from this page, and Build the Pipeline is where they get passed in. For any specific operator's exact behavior, see the HomOps Reference.