Utilities¶
Exceptions¶
Custom exception hierarchy for PyFE4AI.
All scheme-level exceptions inherit from FEError, allowing consumers
to catch broad (except FEError) or narrow (except FEValidationError).
- exception pyfe4ai.utils.exceptions.FEError[source]¶
Bases:
ExceptionBase exception for all PyFE4AI errors.
- exception pyfe4ai.utils.exceptions.FEConfigError[source]¶
Bases:
FEErrorConfiguration or parameter file error (missing, invalid, corrupt).
- exception pyfe4ai.utils.exceptions.FEKeyError[source]¶
Bases:
FEErrorMissing or invalid cryptographic keys / credentials.
- exception pyfe4ai.utils.exceptions.FEValidationError[source]¶
Bases:
FEError,ValueErrorInput validation failure (bound exceeded, shape mismatch, etc.).
- exception pyfe4ai.utils.exceptions.FESchemeError[source]¶
Bases:
FEError,RuntimeErrorInternal scheme logic error (unexpected state, unsupported operation).
Crypto Utilities¶
Core cryptographic primitives: safe random generation, group/prime generation, and hashing.
- pyfe4ai.utils.crypto_utils.generate_group_primes(bits)[source]¶
Generates two safe prime numbers with the restriction:p=2q+1.
- pyfe4ai.utils.crypto_utils.group_generator_threshold_fe(bits, r=2)[source]¶
Generate a safe prime and generator for threshold FE.
- pyfe4ai.utils.crypto_utils.group_generator_paillier(bits)[source]¶
Generates an integer group (p,q,n), where n = pq, and p, q are prime numbers.
Crypto Constants¶
Scheme-type constants and default parameter values used across PyFE4AI.
- class pyfe4ai.utils.crypto_constants.CryptoCONST[source]¶
Bases:
object- TYPE_NONE = 'None'¶
- TYPE_SIFE = 'SIFE'¶
- TYPE_MIFE = 'MIFE'¶
- TYPE_MCFE = 'MCFE'¶
- TYPE_DMCFE = 'dMCFE'¶
- TYPE_DMCFE_LWE = 'dMCFE_LWE'¶
- TYPE_DMCFE_RING_LWE = 'dMCFE_RING_LWE'¶
- TYPE_DMCFE_FH_MULTI_IPE = 'dMCFE_FH_MULTI_IPE'¶
- TYPE_TMCFE = 'tMCFE'¶
- TYPE_TMCFE_LWE = 'tMCFE_LWE'¶
- TYPE_TMCFE_RING_LWE = 'tMCFE_RING_LWE'¶
- TYPE_TMCFE_FH_MULTI_IPE = 'tMCFE_FH_MULTI_IPE'¶
- TYPE_TMIFE = 'tMIFE'¶
- TYPE_TMIFE_LWE = 'tMIFE_LWE'¶
- TYPE_SIFE_PAILLIER = 'SIFE_PAILLIER'¶
- TYPE_SIFE_DAMGARD = 'SIFE_DAMGARD'¶
- TYPE_SIFE_LWE = 'SIFE_LWE'¶
- TYPE_SIFE_FULLYSEC_LWE = 'SIFE_FULLYSEC_LWE'¶
- TYPE_SIFE_RING_LWE = 'SIFE_RING_LWE'¶
- TYPE_SIFE_FH_IPE = 'SIFE_FH_IPE'¶
- TYPE_SIFE_PART_FH_IPE = 'SIFE_PART_FH_IPE'¶
- TYPE_QUADRATIC_SGP = 'QUADRATIC_SGP'¶
- TYPE_QUADRATIC_QUAD = 'QUADRATIC_QUAD'¶
- TYPE_MIFE_PAILLIER = 'MIFE_PAILLIER'¶
- TYPE_MIFE_DAMGARD = 'MIFE_DAMGARD'¶
- TYPE_MIFE_LWE = 'MIFE_LWE'¶
- TYPE_MIFE_FULLYSEC_LWE = 'MIFE_FULLYSEC_LWE'¶
- TYPE_MIFE_FH_IPE = 'MIFE_FH_IPE'¶
- TYPE_MIFE_FH_MULTI_IPE = 'MIFE_FH_MULTI_IPE'¶
- TYPE_MIFE_RING_LWE = 'MIFE_RING_LWE'¶
- TYPE_MCFE_PAILLIER = 'MCFE_PAILLIER'¶
- TYPE_MCFE_DAMGARD = 'MCFE_DAMGARD'¶
- TYPE_MCFE_LWE = 'MCFE_LWE'¶
- TYPE_MCFE_FULLYSEC_LWE = 'MCFE_FULLYSEC_LWE'¶
- TYPE_MCFE_RING_LWE = 'MCFE_RING_LWE'¶
- TYPE_MCFE_FH_MULTI_IPE = 'MCFE_FH_MULTI_IPE'¶
- DEC_STAGE_1 = 'partial_decryption'¶
- DEC_STAGE_2 = 'final_decryption'¶
- CT_STAGE_1 = 'ct_original'¶
- CT_STAGE_2 = 'ct_prime'¶
- SEC_PARAM = 128¶
- SIFE_DEFAULT_ETA = 5¶
- MIFE_ETA = 1¶
- MCFE_ETA = 1¶
- tMIFE_ETA = 1¶
- tMIFE_T = 2¶
- tMCFE_ETA = 1¶
- tMCFE_N = 5¶
- tMCFE_S = 3¶
- tMCFE_T = 2¶
Sampling Utilities¶
Random sampling utilities: uniform vectors/matrices and discrete Gaussians.
- pyfe4ai.utils.sampling_utils.random_below(maximum)[source]¶
- Parameters:
maximum (
mpz)- Return type:
mpz
- pyfe4ai.utils.sampling_utils.rand_uniform_matrix(rows, cols, modulus)[source]¶
Generate a random matrix with entries uniform in [0, modulus).
- pyfe4ai.utils.sampling_utils.rand_uniform_vector(length, modulus)[source]¶
Generate a random vector with entries uniform in [0, modulus).
- pyfe4ai.utils.sampling_utils.discrete_gaussian_matrix(rows, cols, sigma)[source]¶
Sample a matrix from the (rounded) discrete Gaussian distribution.
Samples are drawn from a CSPRNG (
random.SystemRandom, i.e. OS entropy) and rounded to the nearest integer, so this sampler is suitable for LWE noise and secret-key material. Note it is a rounded continuous Gaussian rather than a true discrete-Gaussian sampler, and it is not constant-time; this is adequate for a research prototype but not for production side-channel resistance.- Args:
rows: Number of rows. cols: Number of columns. sigma: Standard deviation for the Gaussian distribution.
Matrix Utilities¶
Integer matrix/vector arithmetic under a modulus.
- pyfe4ai.utils.matrix_utils.matmul_mod(left, right, modulus)[source]¶
Multiply two matrices modulo a given modulus.
- pyfe4ai.utils.matrix_utils.matvec_mod(matrix, vector, modulus)[source]¶
Multiply a matrix by a vector modulo a given modulus.
- pyfe4ai.utils.matrix_utils.vecdot_mod(left, right, modulus)[source]¶
Compute the dot product of two vectors modulo a given modulus.
Modular Arithmetic¶
Modular arithmetic helpers for signed-exponent modular exponentiation.
LWE Utilities¶
LWE parameter derivation, vector centering, and inner-product decoding.
- pyfe4ai.utils.lwe_utils.derive_lwe_parameters(max_plain_bound, bound_y, eta, lwe_n, extra_dimension=None)[source]¶
Derive LWE scheme parameters from plaintext and weight bounds.
- pyfe4ai.utils.lwe_utils.derive_fullysec_lwe_parameters(bound_x, bound_y, eta, lwe_n)[source]¶
Derive fully-secure LWE parameters with multiple noise levels.
- pyfe4ai.utils.lwe_utils.center_lwe_vector(vector, p, q)[source]¶
Scale and center a vector for LWE message extraction.
- pyfe4ai.utils.lwe_utils.decode_lwe_inner_product(value, p, q)[source]¶
Extract a plaintext value from an LWE inner-product ciphertext.
- Parameters:
value (
mpz) – Input value.p (
mpz) – Prime modulus.q (
mpz) – Modulus (or second prime).
- Return type:
Ring-LWE Utilities¶
Ring-LWE helper functions shared across SIFE / MIFE / MCFE Ring-LWE schemes.
These were originally private helpers in sife/ring_lwe.py. They are
extracted here so that cross-package imports reference utils rather than
reaching into another scheme family’s private namespace.
Changed in version 0.2: Added NTT-based polynomial multiplication (O(n log n)) alongside the original naive O(n²) implementation.
Changed in version 0.3: Added next_ntt_prime for NTT-friendly parameter generation,
poly_mul auto-dispatch with cached root of unity.
- pyfe4ai.utils.ring_lwe_utils.ntt_forward(a, q, root)[source]¶
In-place iterative Cooley-Tukey NTT (decimation-in-time).
- pyfe4ai.utils.ring_lwe_utils.ntt_inverse(a, q, root)[source]¶
Inverse NTT: transform back to coefficient domain.
- pyfe4ai.utils.ring_lwe_utils.poly_mul_ntt(a, b, q, root)[source]¶
Polynomial multiplication in Z_q[X]/(X^n+1) via NTT.
- pyfe4ai.utils.ring_lwe_utils.poly_mul(a, b, q)[source]¶
Polynomial multiplication with automatic NTT acceleration.
- pyfe4ai.utils.ring_lwe_utils.next_ntt_prime(lower_bound, ring_n)[source]¶
Find the smallest prime
q >= lower_boundwithq ≡ 1 (mod 2·ring_n).- Parameters:
lower_bound (
mpz) – Lower bound for the search.ring_n (
int) – Polynomial ring dimension.
- Return type:
mpz
- pyfe4ai.utils.ring_lwe_utils.poly_mul_negacyclic(a, b, q)[source]¶
Multiply two polynomials in the negacyclic ring Z_q[X]/(X^n+1).
- pyfe4ai.utils.ring_lwe_utils.matrix_check_bound(matrix, bound)[source]¶
Check whether all matrix entries have absolute value within the bound.
- pyfe4ai.utils.ring_lwe_utils.mat_vec_mul(matrix, vec, q)[source]¶
Multiply a matrix by a polynomial vector modulo q.
- pyfe4ai.utils.ring_lwe_utils.center_matrix(matrix, p, q, ring_n)[source]¶
Scale and round matrix entries for LWE decoding.
Discrete-Log Solver¶
Discrete logarithm solvers with JSON-backed caching for integer and pairing groups.
Provides two strategies:
Dlog table (default): precompute a lookup table of size O(√n) and persist it to a JSON cache file. Subsequent solves are O(√n) lookups against the cached table. Best when the same group parameters are reused across many decrypt calls.
Baby-step giant-step (BSGS) (optional): compute baby-step and giant-step values on the fly without any disk cache. O(√n) time and space per invocation. Useful for one-off solves or when disk caching is undesirable.
- pyfe4ai.utils.dlog_solver.dlog_build_table(g_str, p_str, bound)[source]¶
Build a dlog lookup table for discrete log in
[-bound, bound].
- pyfe4ai.utils.dlog_solver.dlog_table_solve(value, g_str, p_str, bound, table, m, giant)[source]¶
Solve
g^x ≡ value (mod p)withx ∈ [-bound, bound].- Parameters:
- Return type:
- pyfe4ai.utils.dlog_solver.load_or_build_dlog_table(filepath, g_str, p_str, bound)[source]¶
Load a cached dlog table, or generate + save one if stale/missing.
- pyfe4ai.utils.dlog_solver.bsgs_solve_int(value, g_str, p_str, bound)[source]¶
Solve
g^x ≡ value (mod p)withx ∈ [-bound, bound]via BSGS.Uses the standard two-pass approach (matching GoFE / CiFEr reference implementations): search
[0, bound]withg, then search[0, bound]withg⁻¹to cover negative solutions.Unlike the dlog-table approach, this computes baby-step and giant-step values entirely on the fly without reading or writing any disk cache. Suitable for one-off discrete-log recovery or when caching is undesirable.
Complexity: O(√bound) time and space.
- Parameters:
- Return type:
- Returns:
The discrete logarithm x.
- Raises:
ValueError – If no solution is found within the bound.
- pyfe4ai.utils.dlog_solver.bsgs_solve_pairing(target, g, h, pairing_group_param, bound)[source]¶
Solve
e(g, h)^x = targetin a pairing group via on-the-fly BSGS.Uses the standard approach (matching CiFEr’s
cfe_baby_giant_FP12): build one baby-step table fore(g,h)and simultaneously check bothtargetandtarget⁻¹in each giant step, covering[-bound, bound]in a single loop.Computes baby-step and giant-step values entirely in memory without persisting any lookup table.
- Parameters:
- Return type:
- Returns:
The discrete logarithm x.
- Raises:
ValueError – If no solution is found within the bound.
- class pyfe4ai.utils.dlog_solver.PairingDLogCacheMixin[source]¶
Bases:
objectBounded discrete-log recovery helper for pairing-based IPFE-style schemes.
Uses a cached dlog lookup table by default. An on-the-fly BSGS fallback is available via
_solve_dlog_bsgs().This mixin is intentionally separate from higher-level policy composition: policy composition and numeric recovery are different concerns.
ML Adapter¶
ML framework adapter layer for PyFE4AI.
Provides two high-level APIs that hide FE complexity from ML engineers:
- FL aggregation (
eta=1, ndarray helpers): Encrypt per-element gradients from n clients, aggregate with weights.
>>> wrapper = FESchemeWrapper("mcfe", "lwe", keygen_cfg, crypto_cfg) >>> enc = encrypt_gradient(grad_array, wrapper, label="round-1") >>> result = aggregate_gradients( ... {"c0": enc0, "c1": enc1}, wrapper, weights, label="round-1")
- Encrypted inference (
eta=feature_dim, vector mode): Encrypt a feature vector, compute
⟨x, w⟩without revealing x.>>> wrapper = FESchemeWrapper("sife", "lwe", keygen_cfg, crypto_cfg) >>> enc = encrypt_features(feature_vec, wrapper) >>> score = compute_linear(enc, wrapper, model_weights)
PyTorch is optional — functions accept both numpy.ndarray and
torch.Tensor inputs.
- pyfe4ai.utils.ml_adapter.tensor_to_ndarray(t)[source]¶
Convert a PyTorch tensor to a numpy array (detach + cpu + numpy).
- class pyfe4ai.utils.ml_adapter.FESchemeWrapper(scheme_type, variant, keygen_config, *, precision=0, qmode='decimal')[source]¶
Bases:
objectUnified wrapper around any PyFE4AI scheme.
Manages the KeyGenerator lifecycle (setup + key distribution) and provides a consistent encrypt / decrypt surface regardless of the underlying scheme family.
Parameters¶
- scheme_typestr
"sife","mcfe","mife", or"quadratic".- variantstr
"ddh","lwe","paillier","damgard","ring_lwe","quad", or"sgp".- keygen_configdict
Configuration dict for the KeyGenerator (
sec_param,eta,n,bound_x, etc.).- precisionint
Quantization precision (default 0 — no quantization).
- qmodestr
Quantization mode:
"decimal"or"binary"(default"decimal").
- param scheme_type:
- type scheme_type:
- param variant:
- type variant:
- param keygen_config:
- type keygen_config:
- param precision:
- type precision:
int, default:0- param qmode:
- type qmode:
str, default:'decimal'
- class pyfe4ai.utils.ml_adapter.EncryptedGradient(ciphertexts, shape, precision, mode, nid)[source]¶
Bases:
objectEncrypted gradient array for FL aggregation.
Produced by
encrypt_gradient().
- class pyfe4ai.utils.ml_adapter.EncryptedFeatures(ciphertext, dim, precision, mode)[source]¶
Bases:
objectEncrypted feature vector for inference.
Produced by
encrypt_features().
- pyfe4ai.utils.ml_adapter.encrypt_gradient(gradient, wrapper, *, nid='nid_default', label=None)[source]¶
Encrypt a gradient array for federated aggregation.
- Parameters:
- Return type:
- pyfe4ai.utils.ml_adapter.aggregate_gradients(encrypted, wrapper, weights, *, sid='sid_agg', label=None)[source]¶
Decrypt and aggregate encrypted gradients from multiple clients.
- Parameters:
encrypted (
dict[str,EncryptedGradient]) – Encrypted data container.wrapper (
FESchemeWrapper) – FE scheme wrapper instance.weights (
dict[str,float|int|list]) – Weight vector or dict.sid (
str, default:'sid_agg') – Session / decryption-key identifier.label (
str|None, default:None) – Encryption label for replay protection.
- Return type:
- pyfe4ai.utils.ml_adapter.encrypt_features(features, wrapper, *, nid='nid_default')[source]¶
Encrypt a feature vector for privacy-preserving inference.
- Parameters:
wrapper (
FESchemeWrapper) – FE scheme wrapper instance.nid (
str, default:'nid_default') – Node identifier.
- Return type:
- pyfe4ai.utils.ml_adapter.compute_linear(encrypted, wrapper, weights, *, sid='sid_infer')[source]¶
Compute ⟨features, weights⟩ on encrypted features.
- Parameters:
encrypted (
EncryptedFeatures) – Encrypted data container.wrapper (
FESchemeWrapper) – FE scheme wrapper instance.sid (
str, default:'sid_infer') – Session / decryption-key identifier.
- Return type:
Quantization¶
Precision management toolkit for functional encryption on real-valued data.
FE schemes operate on integers, but AI/ML workloads use floats. This module provides three tools to bridge the gap:
QuantizationConfig— float↔int conversion with configurable scaling (decimalorbinarymode).estimate_bounds()— auto-computebound_x,bound_yand discrete-log table requirements from sample data.analyze_precision_loss()— report quantization error metrics.
- class pyfe4ai.utils.quantization.QuantizationConfig(precision=3, mode='decimal')[source]¶
Bases:
objectImmutable quantization strategy for float↔int conversion.
Parameters¶
- precisionint
Number of fractional digits (decimal) or bits (binary) to preserve.
- modestr
"decimal"scales by10**precision(compatible with existing PyFE4AI ndarray helpers)."binary"scales by2**precision(avoids base-10 rounding artefacts, better for ML weights).
- pyfe4ai.utils.quantization.estimate_bounds(x_data, y_weights, precision, eta=None, mode='decimal')[source]¶
Auto-compute safe FE bounds from sample data.
- Parameters:
- Return type:
- pyfe4ai.utils.quantization.validate_bounds(bound_x, bound_y, eta, precision)[source]¶
Check whether configured bounds are safe for FE operations.
Pairing Backend¶
Helpers for optional pairing-based dependencies.
Pairing Utilities¶
Pairing-based helper functions shared across FH-IPE / FH-Multi-IPE / Quadratic schemes.
These were originally private helpers in sife/fh_ipe_pairing.py and
mife/fh_multi_ipe_pairing.py. They are extracted here so that
cross-package imports reference utils rather than reaching into
another scheme family’s private namespace.
- pyfe4ai.utils.pairing_utils.mat_vec_mod(matrix, vector, modulus)[source]¶
Multiply a matrix by a vector modulo a given modulus.
- pyfe4ai.utils.pairing_utils.vector_add_mod(lhs, rhs, modulus)[source]¶
Add two vectors element-wise modulo a given modulus.
- pyfe4ai.utils.pairing_utils.vector_scalar_mod(vector, scalar, modulus)[source]¶
Multiply a vector by a scalar modulo a given modulus.
- pyfe4ai.utils.pairing_utils.to_zr(group, value)[source]¶
Convert an integer to a ZR element in the pairing group.
- pyfe4ai.utils.pairing_utils.matrix_inverse_mod(matrix, modulus)[source]¶
Compute the modular inverse of a matrix via Gaussian elimination.
- pyfe4ai.utils.pairing_utils.bounded_discrete_log_gt(group, base, target, bound)[source]¶
Solve a bounded discrete logarithm in GT via baby-step giant-step.