fhelium.engine.hybrid_keyswitch
CKKS key-switching helpers.
The central operation in this file is applying a key-switch key to one ciphertext component. In standard CKKS/RNS terminology the hot path is:
- Split the source component into hybrid-RNS decomposition digits.
- Convert each composite digit's residues to mixed-radix components.
- Apply ModUp/basis extension to each digit on the active
basis. - NTT the extended digit, multiply it by the matching key digit, and accumulate the two switched output components in the
basis. - INTT the accumulators and ModDown/divide-by-
back to the active basis. - Add the first correction component to the original ciphertext component.
Hybrid decomposition digits and mixed-radix components are named separately so the code maps directly to the standard CKKS key-switch flow.
PreparedRotationKeySwitch
class View source
PreparedRotationKeySwitch(level: int, batch_shape: tuple[int, ...], ntt_digits_qp: torch.Tensor)Reusable NTT-domain QP digits for rotations of one component.
Decomposition, ModUp, and forward NTT are independent of the rotation step and are therefore materialized once. Coefficient-domain and mixed-radix intermediates are deliberately not retained: consumers need only the final NTT digits, while tests can construct debug references explicitly without expanding the production artifact representation.
ntt_digits_qp is an integral tensor on the engine device with shape [digit, *batch, limb, ntt_index]. Limb order is the exact active rns_layout.prime_ids(level, include_p=True) order; every residue is Montgomery/lazy. digit is local active order and callers resolve each stable key_digit_index separately before indexing key storage.
Attributes
| Name | Type | Default/value |
|---|---|---|
level | int | |
batch_shape | tuple[int, ...] | |
ntt_digits_qp | torch.Tensor |
HybridKeySwitcher
class View source
HybridKeySwitcher(*, config: CkksConfig, rns_runtime: RnsRuntime, moddown_p_drop_inverses_montgomery_by_level: list[torch.Tensor], direct_digit_consumer: DirectKeySwitchDigitConsumer, galois_generator: int=3)Execute CKKS hybrid-RNS direct and prepared key switching.
apply_key_switch
method
def apply_key_switch(component: torch.Tensor, key_switch_key: KeySwitchKey, level: int) -> tuple[torch.Tensor, torch.Tensor]: ...prepare_rotation_digits
method
def prepare_rotation_digits(component: torch.Tensor, level: int) -> PreparedRotationKeySwitch: ...Materialize only reusable NTT-domain QP digits for rotate-many.