hetorch.backend.fake
Fake backend for testing and debugging
This module provides a fake HE backend that simulates homomorphic encryption operations using PyTorch tensors. It supports realistic noise simulation to help validate compilation passes and predict when bootstrapping is needed.
Classes
FakeBackend(simulate_noise: <class 'bool'>, initial_noise_budget: <class 'float'>, noise_model: typing.Optional[hetorch.backend.fake.NoiseModel], warn_on_low_noise: <class 'bool'>, noise_warning_threshold: <class 'float'>)
Fake backend for testing and debugging
Simulates HE operations without actual encryption:
- CAdd -> torch.add
- CMult -> torch.mul
- Rotate -> torch.roll
Supports realistic noise simulation when enabled.
Args: simulate_noise: If True, track noise budget with realistic model initial_noise_budget: Initial noise budget for new ciphertexts noise_model: Custom noise model (uses default if None) warn_on_low_noise: If True, warn when noise budget is low noise_warning_threshold: Threshold for low noise warnings
Methods:
__init__(self, simulate_noise: bool = False, initial_noise_budget: float = 100.0, noise_model: Optional[hetorch.backend.fake.NoiseModel] = None, warn_on_low_noise: bool = True, noise_warning_threshold: float = 20.0)
Initialize self. See help(type(self)) for accurate signature.
bootstrap(self, ct: hetorch.backend.fake.FakeCiphertext) -\> hetorch.backend.fake.FakeCiphertext
Bootstrap ciphertext - simulated as resetting noise budget
cadd(self, ct1: hetorch.backend.fake.FakeCiphertext, ct2: hetorch.backend.fake.FakeCiphertext) -\> hetorch.backend.fake.FakeCiphertext
Ciphertext addition (simulated as tensor addition)
cmult(self, ct1: hetorch.backend.fake.FakeCiphertext, ct2: hetorch.backend.fake.FakeCiphertext) -\> hetorch.backend.fake.FakeCiphertext
Ciphertext multiplication (simulated as tensor multiplication)
decrypt(self, ct: hetorch.backend.fake.FakeCiphertext) -\> torch.Tensor
Decrypt a ciphertext (simulated - just returns the tensor)
encrypt(self, tensor: torch.Tensor, info: Optional[hetorch.core.ciphertext.CiphertextInfo] = None) -\> hetorch.backend.fake.FakeCiphertext
Encrypt a plaintext tensor (simulated - just wraps the tensor)
get_cost_model(self) -\> hetorch.backend.cost_model.CostModel
Return cost model for fake backend
get_supported_operations(self) -\> List[str]
Return list of supported operations
padd(self, ct: hetorch.backend.fake.FakeCiphertext, pt: torch.Tensor) -\> hetorch.backend.fake.FakeCiphertext
Add plaintext to ciphertext
pmult(self, ct: hetorch.backend.fake.FakeCiphertext, pt: torch.Tensor) -\> hetorch.backend.fake.FakeCiphertext
Multiply ciphertext by plaintext
relinearize(self, ct: hetorch.backend.fake.FakeCiphertext) -\> hetorch.backend.fake.FakeCiphertext
Relinearize ciphertext (reduce size after cmult)
rescale(self, ct: hetorch.backend.fake.FakeCiphertext) -\> hetorch.backend.fake.FakeCiphertext
Rescale ciphertext (CKKS) - simulated as no-op on data
rotate(self, ct: hetorch.backend.fake.FakeCiphertext, steps: int) -\> hetorch.backend.fake.FakeCiphertext
Ciphertext rotation (simulated as tensor roll)
FakeCiphertext(data: <class 'torch.Tensor'>, _info: <class 'hetorch.core.ciphertext.CiphertextInfo'>)
Simulated ciphertext using PyTorch tensor
Attributes: data: Underlying plaintext tensor (simulating encrypted data) _info: Ciphertext metadata
Methods:
__init__(self, data: torch.Tensor, _info: hetorch.core.ciphertext.CiphertextInfo) -\> None
Initialize self. See help(type(self)) for accurate signature.
NoiseModel(initial_noise_budget: <class 'float'>, add_noise_bits: <class 'float'>, mult_noise_factor: <class 'float'>, rotate_noise_bits: <class 'float'>, rescale_noise_reduction: <class 'float'>, bootstrap_noise_reset: <class 'float'>, pmult_noise_factor: <class 'float'>, relinearize_noise_bits: <class 'float'>)
Realistic noise growth model for HE operations
This model simulates noise growth based on HE theory:
- Addition: noise grows additively
- Multiplication: noise grows multiplicatively
- Rotation: minimal noise growth
- Rescaling: reduces noise
Noise is measured in bits of precision remaining.
Methods:
__init__(self, initial_noise_budget: float = 100.0, add_noise_bits: float = 1.0, mult_noise_factor: float = 2.0, rotate_noise_bits: float = 0.5, rescale_noise_reduction: float = 0.9, bootstrap_noise_reset: float = 100.0, pmult_noise_factor: float = 1.5, relinearize_noise_bits: float = 0.3)
Initialize noise model with configurable parameters
Args: initial_noise_budget: Initial noise budget in bits add_noise_bits: Noise bits added by addition mult_noise_factor: Multiplicative factor for cmult noise rotate_noise_bits: Noise bits added by rotation rescale_noise_reduction: Noise reduction factor for rescaling bootstrap_noise_reset: Noise budget after bootstrapping pmult_noise_factor: Multiplicative factor for pmult noise relinearize_noise_bits: Noise bits added by relinearization
compute_add_noise(self, noise1: float, noise2: float) -\> float
Compute noise after ciphertext addition
In HE, addition noise grows as: noise_result ≈ noise1 + noise2 + small_term We model this by taking the max and adding a small constant.
compute_bootstrap_noise(self) -\> float
Compute noise after bootstrapping
Bootstrapping refreshes the ciphertext, resetting noise to initial level.
compute_mult_noise(self, noise1: float, noise2: float) -\> float
Compute noise after ciphertext multiplication
In HE, multiplication noise grows as: noise_result ≈ noise1 * noise2 * factor This is the most expensive operation in terms of noise growth. We model this by reducing the minimum noise budget significantly.
compute_pmult_noise(self, noise: float) -\> float
Compute noise after plaintext multiplication
Plaintext multiplication increases noise less than ciphertext multiplication.
compute_relinearize_noise(self, noise: float) -\> float
Compute noise after relinearization
Relinearization adds a small amount of noise but is necessary after cmult.
compute_rescale_noise(self, noise: float) -\> float
Compute noise after rescaling (CKKS)
Rescaling reduces noise by removing one modulus level. In practice, this improves the noise budget by a fixed amount.
compute_rotate_noise(self, noise: float) -\> float
Compute noise after rotation
Rotation adds minimal noise in most HE schemes.
is_noise_budget_exhausted(self, noise_budget: float, threshold: float = 10.0) -\> bool
Check if noise budget is exhausted
Args: noise_budget: Current noise budget in bits threshold: Minimum safe noise budget
Returns: True if noise budget is below threshold