fhelium.experimental.bootstrap.reduction
Periodic functions that remove approximate CKKS carries.
CosineDoubleAngleReduction
class View source
CosineDoubleAngleReduction(input_bound: int, double_angle_iterations: int, approximator: Any, evaluator: Any, fuse_input_normalization: bool = False, retain_ntt: bool = False, maximum_plaintext_error: float = 0.001)Reduce one real branch with a cosine seed and double-angle chain.
input_bound is the positive integer double_angle_iterations, the seed is
and iteration
Thus
reference(values) always takes normalized evaluate(...) takes raw fuse_input_normalization=False, dividing by
The homomorphic input is a two-component Q ciphertext in either coefficient/standard or NTT/Montgomery representation, with payload axes [component, *batch, limb, coefficient], active prime_ids, and actual scale matching the arithmetic owner's target at the input depth. Evaluation is functional. With retain_ntt=True, a coefficient input is transformed once and the polynomial and double-angle chain retain NTT/Montgomery form until one final inverse transform. Otherwise each multiplication returns to the input representation. Rescale removes one Q group and divides actual scale by its product. The output uses the input representation, batch and component axes, Q basis, and context; its depth advances by required_depths, its limb axis contains the corresponding suffix of prime_ids, and its actual scale follows the arithmetic owner's depth schedule.
More iterations reduce the seed frequency but each iteration costs one ciphertext multiplication, relinearization, and rescale depth. Neither the class nor evaluate measures the encrypted branch range; the caller must establish
Attributes
| Name | Type | Default/value |
|---|---|---|
requires_relinearization | True | |
input_bound | int | |
double_angle_iterations | int | |
approximator | Any | |
evaluator | Any | |
fuse_input_normalization | bool | False |
retain_ntt | bool | False |
maximum_plaintext_error | float | 0.001 |
polynomial
property
polynomial: PolynomialApproximationFit the low-frequency seed in normalized coordinate
For double_angle_iterations, the returned Chebyshev or power series approximates
Its coefficient basis is selected by approximator; coefficients use that basis's ascending-degree convention.
approximation_error
property
approximation_error: floatSample
The grid spans normalized
fused_input_divisor
property
fused_input_divisor: floatReturn
required_depths
property
required_depths: intCount explicit division, polynomial depth, and recurrence depth.
evaluate
method
def evaluate(arithmetic: BootstrapArithmetic, ciphertext: Ciphertext, *, relinearization_key: RelinearizationKey | None, conjugation_key: ConjugationKey | None=None) -> Ciphertext: ...Evaluate
With non-fused normalization the input represents raw ciphertext.depth + required_depths. Input storage is not mutated or aliased by the result.
reference
method
def reference(values: np.ndarray) -> np.ndarray: ...Evaluate the plaintext oracle on normalized coordinates
values may have any NumPy-broadcastable shape and that shape is preserved. Unlike non-fused evaluate, this method never divides by values / input_bound. The target is
ExponentialSquaringReduction
class View source
ExponentialSquaringReduction(input_bound: int, degree: int, evaluator: Any = BalancedPowerEvaluator(), fuse_input_normalization: bool = False)Reduce one real branch through a truncated exponential and squaring.
Let input_bound,
Repeated squaring computes
reference(values) always consumes normalized evaluate(...) consumes raw fuse_input_normalization=False; with fusion enabled its caller must provide
The ciphertext state, axes, functional behavior, depth transition, and depth-dependent scale schedule are the same as for CosineDoubleAngleReduction. This strategy additionally requires a conjugation key. It returns a two-component coefficient-domain, standard-RNS Q ciphertext at ciphertext.depth + required_depths, with the corresponding active prime_ids and the arithmetic owner's target scale.
Attributes
| Name | Type | Default/value |
|---|---|---|
requires_relinearization | True | |
input_bound | int | |
degree | int | |
evaluator | Any | BalancedPowerEvaluator() |
fuse_input_normalization | bool | False |
polynomial
property
polynomial: PolynomialApproximationReturn ascending power coefficients for
Entry
squaring_iterations
property
squaring_iterations: intReturn
fused_input_divisor
property
fused_input_divisor: floatReturn
required_depths
property
required_depths: intCount normalization, polynomial DAG, squarings, and sine scaling.
evaluate
method
def evaluate(arithmetic: BootstrapArithmetic, ciphertext: Ciphertext, *, relinearization_key: RelinearizationKey | None, conjugation_key: ConjugationKey | None=None) -> Ciphertext: ...Evaluate
Non-fused evaluation first maps raw
reference
method
def reference(values: np.ndarray) -> np.ndarray: ...Evaluate the plaintext oracle on normalized coordinates
The input shape is preserved. This method never divides by values / input_bound. It models polynomial truncation and repeated squaring but not CKKS error.