fhelium.engine.key_generator
CKKS secret, public, rotation, conjugation, and key-switch key generation.
CkksKeyGenerator
class View source
CkksKeyGenerator(*, config: CkksConfig, context: CkksContextSpec, device: torch.device, rng: Csprng, rns_runtime: RnsRuntime, p_product_montgomery_q: torch.Tensor, galois_generator: int=3)Construct dense CKKS keys on one process-local execution device.
Key payloads use integral dtype and exact canonical prime rows. Secret-key data is [limb, ntt_index]; public keys are [key_component, limb, ntt_index]; key-switch keys are [key_digit, key_component, limb, ntt_index]. Returned keys are always NTT/Montgomery/lazy at level zero in the stated Q or QP basis and own their payload storage. Local digit_index is resolved to stable key_digit_index before key tensor indexing.
create_secret_key
method
def create_secret_key(*, modulus_basis: ModulusBasis='QP') -> SecretKey: ...Sample ternary
Output shape is [limb, ntt_index] with exact Q or QP prime_ids selected by modulus_basis. Sampling and all temporary transitions are functional from the caller's perspective.
create_public_key
method
def create_public_key(secret_key: SecretKey, *, modulus_basis: ModulusBasis='Q', uniform_component: torch.Tensor | None=None) -> PublicKey: ...Generate (k_0,k_1) satisfying
Output is integral [key_component=2, limb, ntt_index] in level-zero NTT/Montgomery form with exact Q or QP rows. secret_key and optional uniform_component are read-only and never alias the returned stacked tensor.
create_key_switch_key
method
def create_key_switch_key(source_secret_key: SecretKey, destination_secret_key: SecretKey, *, uniform_component_by_key_digit: torch.Tensor | None=None) -> KeySwitchKey: ...Create a hybrid-RNS key from source to destination secret relation.
Key construction belongs here rather than in the key-switch executor: it repeatedly creates public-key encryptions and does not participate in either the direct-streaming or prepared execution plans.
Stable key digit [key_digit, key_component=2, QP_limb, ntt_index] in NTT/Montgomery lazy form and exact level-zero QP order. Input keys and optional uniform components are not mutated or aliased.
create_relinearization_key
method
def create_relinearization_key(secret_key: SecretKey) -> RelinearizationKey: ...Return QP key material that switches the
The returned state and layout equal create_key_switch_key; the input secret key remains NTT/Montgomery QP and is not mutated.
create_rotation_key
method
def create_rotation_key(rotation_step: int, *, uniform_component_by_key_digit: torch.Tensor | None=None, secret_key: SecretKey) -> RotationKey: ...Construct QP key material from
rotation_step follows signed slot displacement and is stored as metadata. The distinct galois_element
create_conjugation_key
method
def create_conjugation_key(secret_key: SecretKey) -> ConjugationKey: ...Construct QP key material from
Output uses key-switch-key axes and NTT/Montgomery QP state; the input secret key remains unchanged.