Core¶
What every scheme shares: the key-generator and crypto base classes with
the parameter cache (base), the config classes and
option rules (config), the serialized objects
(formats) and their version markers
(versions), security profiles
(profiles), review status (status),
one-time precomputations (one_time), the fork handler
(forksafe), exceptions and constants.
The status and security-profile modules (pyfe4ai.core.status,
pyfe4ai.core.profiles) are documented on Security & Status.
Scheme Registry¶
The registry of the schemes: one entry per scheme, the single source of what the library records about it.
Every registered scheme has an id "family/variant" – "sife/ddh",
"mcfe/ring_lwe", "mcfe/ring_lwe_threshold" – and a Scheme
entry in SCHEMES with
its module and its classes: the key generator and the crypto class, named after the id (
class_name(); imported on first use), and the config class ofpyfe4ai.core.config;its kind (
KINDS): the family of parameters the security profiles size, and the reason thestandardprofile refuses it, if it does (pyfe4ai.core.config.resolve()applies both; the minima and presets of each kind are inpyfe4ai.core.config);its review status (
SchemeStatus);its capabilities (
CAPABILITIES).
The other tables of the library are derived from it: the status table
(pyfe4ai.core.status.SCHEME_STATUS) with the README and
documentation tables rendered from it, the kinds of the security profiles
(pyfe4ai.core.profiles.SCHEME_KIND), the schemes of the ML adapter
(pyfe4ai.ml.FESchemeWrapper: classes, labels, the servers it runs,
the group variants) and the benchmark scripts. tests/api/test_registry.py
checks the entries against the code.
create() builds a scheme’s key generator by id and returns it with the
scheme’s crypto class; get_scheme() and list_schemes() query the
registry. All three are exported by pyfe4ai:
import pyfe4ai
kg, MCFE = pyfe4ai.create("mcfe/ring_lwe", n=3, bound_x=10, bound_y=10)
pyfe4ai.list_schemes("mcfe", capabilities="threshold")
pyfe4ai.get_scheme("mcfe/ring_lwe").capabilities
Class names. The classes of a scheme are named after its id, one name
per class: Threshold or Decentralized for the variants with that
suffix, the family (SIFE, MIFE, MCFE, Quadratic), then the
rest of the variant in CamelCase with its acronyms in capitals; the key
generator adds KeyGenerator, the config class Config:
sife/ddh – SIFEDDH, SIFEDDHKeyGenerator, SIFEDDHConfig;
mcfe/ring_lwe_threshold – ThresholdMCFERingLWE;
mcfe/ddh_decentralized – DecentralizedMCFEDDH;
mife/fh_multi_ipe_pairing – MIFEFHMultiIPEPairing;
quadratic/miqfe – QuadraticMIQFE.
- pyfe4ai.core.registry.STATUSES = ('reviewed', 'experimental', 'unreviewed', 'known-insecure')¶
The review status values, best first.
- pyfe4ai.core.registry.FIDELITIES = ('faithful', 'adapted', 'ad-hoc', 'unknown')¶
The fidelity values.
- class pyfe4ai.core.registry.SchemeStatus(module, status, fidelity, reference, note='', issue='')[source]¶
Bases:
objectReview status of one registered scheme.
status"reviewed": the implementation was checked against the cited construction and no security defect is known."experimental": implemented and checked here, but the construction or its security argument is our own rather than a published one; no defect is known."unreviewed": not yet checked against its paper; no defect is known, but none was looked for systematically either."known-insecure": a concrete privacy defect is known (seeissue); the scheme computes correct results but must only be used for functionality or performance experiments.fidelity"faithful": the published construction as written."adapted": the published construction with documented deviations or extensions (seenote)."ad-hoc": a composition with no published construction behind it."unknown": not assessed (unreviewed schemes).
moduleis the scheme’s module,referencethe construction it implements. All schemes additionally share the caveats of the README (research prototype, toy default parameters, no side-channel hardening).
- pyfe4ai.core.registry.KINDS = {'dcr': 'decisional composite residuosity (Paillier)', 'dl': 'discrete log in a safe-prime group (DDH, Damgard / MDDH)', 'ec': 'DDH over ristretto255 (a fixed group)', 'lwe': 'dense LWE without a public matrix (the ABMPSW20 MCFE family)', 'lwe_abdp15': 'LWE with a seeded public matrix (the ABDP15 IPFE)', 'lwe_matrix': 'LWE with a public matrix, ALS16', 'pairing': 'asymmetric pairings', 'ring_lwe': 'Ring-LWE'}¶
The kinds of scheme the security profiles size parameters for (see
pyfe4ai.core.profiles).
- pyfe4ai.core.registry.CAPABILITIES = {'binary_ct': "binary ciphertexts (crypto option ct_format='binary', or the public parameters' format)", 'decentralized': 'the clients derive shares of each functional key, which the decryptor combines (derive_function_decryption_key_share, combine_function_decryption_key_share)', 'labels': 'ciphertexts and functional keys are bound to a label (the MCFE family)', 'ml_servers': 'the ML adapter runs the decryption servers in-process (pyfe4ai.ml: aggregate_gradients, prepare_aggregation)', 'pairing': 'runs over a pairing group (pairing_group_param; BLS12-381 by default)', 'rns': "an RNS modulus, a product of NTT primes (key generator option ring_modulus='rns')", 'threshold': 'functional keys are shared among s servers; t partial decryptions decrypt (share_decrypt, combine_decrypt)'}¶
The capabilities a scheme may have, with what they mean.
labels,threshold,decentralizedandpairingfollow from the id and the kind; the others are declared per scheme.
- pyfe4ai.core.registry.FAMILIES = {'mcfe': 'MCFE', 'mife': 'MIFE', 'quadratic': 'Quadratic', 'sife': 'SIFE'}¶
The family part of the class names.
- pyfe4ai.core.registry.class_name(scheme, role='')[source]¶
The name of a class of scheme (
"family/variant"): the crypto class forrole="", else the name with role appended ("KeyGenerator","Config"); see the module docstring.
- class pyfe4ai.core.registry.Scheme(family, variant, module, kind, status, capabilities, refused='', group=None, instance_of=None)[source]¶
Bases:
objectA registered scheme (see the module docstring).
The classes are imported when first read:
key_generator,crypto,config.- Parameters:
- capabilities: frozenset¶
See
CAPABILITIES.
- group: str | None = None¶
The group of a scheme that instantiates another variant of its family in a group of its own (the ML adapter’s
groupoption), such asristretto255forddh_ristretto255.
- instance_of: str | None = None¶
The variant that such a scheme instantiates (
ddhforddh_ristretto255).
- property crypto: type¶
The crypto class, whose objects encrypt, decrypt or serve (imports the module).
- property config: type¶
The config class (
pyfe4ai.core.config).
- has(*capabilities)[source]¶
Whether the scheme has every one of capabilities.
- Raises:
FEValidationError – For a name not in
CAPABILITIES.- Parameters:
capabilities (
str)- Return type:
- pyfe4ai.core.registry.SCHEMES: tuple[Scheme, ...]¶
Every registered scheme, in the order of the tables derived from them.
- pyfe4ai.core.registry.get_scheme(scheme)[source]¶
The registry entry of scheme: an id
"family/variant"or a(family, variant)pair.
- pyfe4ai.core.registry.list_schemes(family=None, *, capabilities=(), status=None, kind=None)[source]¶
The ids of the registered schemes, in registry order, optionally only those of family, with all of capabilities (
CAPABILITIES), of review status (STATUSES) or of kind (KINDS).
- class pyfe4ai.core.registry.CreatedScheme(key_generator, crypto)[source]¶
Bases:
NamedTupleWhat
create()returns:key_generator, crypto = create(...).
- pyfe4ai.core.registry.create(scheme, config=None, **options)[source]¶
Build the key generator of scheme and return it with the scheme’s crypto class.
create("mcfe/ring_lwe", config)isMCFERingLWEKeyGenerator(config)together withMCFERingLWE: the key generator is built exactly as by its class (the config is converted to the scheme’s config class and completed by its security profile, seepyfe4ai.core.config), and not set up: call itssetup(), then hand out the public parameters and keys:kg, SIFEDDH = pyfe4ai.create("sife/ddh", eta=3) kg.setup() pp = kg.get_public_parameters() client = SIFEDDH({"keys": {"pp": pp, "sk": kg.get_private_keys()}})
- Parameters:
scheme (
str|tuple[str,str]) – The scheme’s id"family/variant"(list_schemes()), or(family, variant).config (
Mapping|None, default:None) – The key generator’s config (a mapping);Nonefor an empty one (the scheme’s defaults,toyprofile).**options – Config entries, added to config (and replacing its entries of the same name).
- Return type:
- Returns:
CreatedScheme(key_generator, crypto).- Raises:
FEValidationError – For an unknown scheme, a config that is not a mapping, or a config the key generator refuses.
The registered schemes (standard: whether the standard profile
gives the scheme parameters; see Security & Status):
Base Classes and the Parameter Cache¶
Abstract base classes shared by all IPFE schemes.
- pyfe4ai.core.base.CACHE_DIR_ENV = 'PYFE4AI_CACHE_DIR'¶
Environment variable that sets the parameter cache directory (see
cache_dir()).
- pyfe4ai.core.base.default_cache_dir()[source]¶
The per-user cache directory of PyFE4AI on this platform.
~/Library/Caches/pyfe4aion macOS,%LOCALAPPDATA%\pyfe4ai\Cacheon Windows, and$XDG_CACHE_HOME/pyfe4aielsewhere (~/.cache/pyfe4aiifXDG_CACHE_HOMEis unset or not an absolute path) – the directories ofplatformdirs.user_cache_dir("pyfe4ai", appauthor=False).- Return type:
- pyfe4ai.core.base.cache_dir(explicit=None)[source]¶
The parameter cache directory: explicit (the
cache_direntry of a key generator’s or crypto object’s config) if given, else thePYFE4AI_CACHE_DIRenvironment variable if set and not empty, elsedefault_cache_dir(). A relative path is relative to the working directory.Key generators keep their records in
<cache_dir>/authority/<scheme type>/(seeParameterCacheMixin). The cache is trusted: it must not be writable by others.- Raises:
FEValidationError – If explicit is not a non-empty path.
- Return type:
- class pyfe4ai.core.base.ParameterCacheMixin[source]¶
Bases:
objectMixin that provides JSON-based parameter caching with validation.
Subclasses must set
_scheme_type(a CryptoCONST string) and implement_param_verification,_apply_parameters, and_generate_and_save. The records are kept inconfig_folder, theauthorityfolder of the cache directory (cache_dir(): thecache_direntry of the config,PYFE4AI_CACHE_DIRor the per-user cache directory).
- class pyfe4ai.core.base.IPFEAbsKeyGenerator(config, **kwargs)[source]¶
Bases:
objectAbstract base for all inner-product FE key generators.
Subclasses implement
setup()(generate keys),get_public_parameters(),get_private_keys(), andget_decryption_keys().- Parameters:
config (
dict) – Scheme configuration (a mapping, converted to the scheme’s config class ofpyfe4ai.core.config). Expected keys vary by scheme; common keys includesec_param,eta,n,s,lst_nid,security_profile(seepyfe4ai.core.profiles) andcache_dir(the parameter cache directory, seecache_dir()).
- abstractmethod get_private_keys(nid, **kwargs)[source]¶
Return the private (encryption) keys for client nid.
- abstractmethod get_decryption_keys(sid, **kwargs)[source]¶
Derive a functional decryption key for session sid.
- Parameters:
sid (
str) – A session identifier.**kwargs – Must include
credentialswith afusion_weightentry.
- Return type:
- Returns:
A dict containing the decryption key material.
- Raises:
FEKeyError – If credentials are missing.
FEValidationError – If fusion weights are invalid.
- pyfe4ai.core.base.decoded_layer(values, layer, scale=1)[source]¶
Return the decrypted elements of one ndarray layer, divided by scale.
- Parameters:
- Raises:
FESchemeError – For the first element that did not decrypt – its result is outside the decryption bound, or the key and the ciphertext do not match.
Noneis never turned intoNaN.- Return type:
- pyfe4ai.core.base.PRIVATE_KEY_NOT_A_DICT = "the encryption key (keys['sk']) is not a dict of its fields"¶
The
FEKeyErrortext for an encryption key (keys["sk"]) that is not a dict (raised byIPFEAbsCrypto._check_private_key).
- class pyfe4ai.core.base.IPFEAbsCrypto(config, **kwargs)[source]¶
Bases:
ABCAbstract base for all inner-product FE crypto operations.
Subclasses implement
encrypt_lst_ndarray(),compute_lst_ndarray_ct(), anddecrypt_lst_ndarray_ct().- Parameters:
config (
dict) – Runtime configuration dict containing at leastkeys(a dict withpp,sk, and/ordksub-dicts) and optionallyid,type, andprecision.
- abstractmethod encrypt_lst_ndarray(lst_ndarray, **kwargs)[source]¶
Encrypt a list of ndarray-like plaintexts.
- abstractmethod compute_lst_ndarray_ct(dict_ndarray_ct, **kwargs)[source]¶
Aggregate ciphertexts from multiple clients.
- abstractmethod decrypt_lst_ndarray_ct(dict_ndarray_ct, **kwargs)[source]¶
Decrypt aggregated ndarray ciphertexts.
- Parameters:
dict_ndarray_ct (
dict) – Mapping of client IDs to their ciphertext lists.- Return type:
- Returns:
One float array of decrypted results per layer.
- Raises:
FESchemeError – If an element does not decrypt (see
decoded_layer()).
Serialized Objects¶
The serialized objects of the schemes: their layouts and byte codecs.
Every object that leaves a scheme – public parameters, parameter records,
encryption keys, functional keys and key shares, ciphertexts, partial
decryptions – is a dict (JSON-friendly, with bytes for the binary formats).
Its layout is declared once as a Record:
the fields in wire order, what each holds, and what an absent field means
(versions and their markers: pyfe4ai.core.versions). The schemes build
these dicts with Record.new and read them through record views, so the
dicts themselves are what they were: a record is the dict, not a copy.
binary– the byte codecs of the Ring-LWE ciphertexts and values;lwe– the LWE schemes (ABDP15, FullySec, the ABMPSW20 MCFE);ring_lwe– the Ring-LWE schemes;dl– the discrete-log and DCR schemes;pairing– the pairing schemes (function-hiding IPFE, MIFE and MCFE) and the quadratic schemes;threshold– key shares, replicated pieces and partial decryptions of the threshold schemes.
The base of the serialized-object containers: Record and Field.
A record is a typed view of the dict that is its wire form. It holds that
dict itself – no copy, no conversion – so a record and its dict are always
the same bytes on the wire, key order and unknown fields included:
Record.from_dict(d).to_dict() is d. Reading a field reads the dict as the
code of earlier versions did:
record.nameisd["name"](KeyErrorif the field is absent);record.get("name", default)isd.get("name", default)and"name" in recordis"name" in d, for a declared field only (an undeclared name raisesAttributeError);record.name = value,record.update(...)anddel record.namewrite the dict.
So the checks a scheme makes when it reads a key or a ciphertext stay where
they are, with their exceptions; what a record adds is one declaration of
every field, its order on the wire and what its absence means
(Field(absent=...): the default of earlier versions that a missing
marker stands for, documented here and applied by pyfe4ai.core.versions,
never silently by attribute access). Record.new() builds the dict of a new object in
the declared order.
- pyfe4ai.core.formats.record.ABSENT: Any = ABSENT¶
Marks a field that
Record.new()leaves out (an optional field whose absence has a meaning, e.g. the JSON format of versions <= 0.3.0).
- class pyfe4ai.core.formats.record.Field(doc='', *, absent=<object object>)[source]¶
Bases:
objectA field of a
Record, by its wire name (the attribute name).- Parameters:
doc (
str, default:'') – What the field holds (its type and encoding).absent (
Any, default:<object object at 0x7062278c6a40>) – What a missing field means, for fields that versions or options leave out: documentation of the default thatpyfe4ai.core.versions(or the scheme) applies, whichtests/config/test_versions.pychecks against it;Nonewhere it depends on the context (the doc says how). Reading a missing field raisesKeyErrorasd[name]does, whatever it means.
- class pyfe4ai.core.formats.record.Record(raw)[source]¶
Bases:
objectA serialized object: a typed view of its wire dict (see the module docstring).
Subclasses declare their fields as
Fieldattributes, in wire order (a base class’s fields first), or give that order inORDERwhen a subclass’s fields go between its base’s.- classmethod from_dict(data)[source]¶
The record of a wire dict (the dict itself, not a copy; its fields are read when used, with the checks of each use).
- classmethod new(**values)[source]¶
A new record: a dict of values in the declared order; a value
ABSENTleaves its field out.- Raises:
TypeError – For a name that is not a field.
- classmethod extend(base, **values)[source]¶
dict(base, **values)as a record: a new dict with base’s fields in their order, then values (a field of base keeps its place, as with a dict).- Raises:
TypeError – For a name of values that is not a field.
- get(name, default=None)[source]¶
d.get(name, default)for the declared field name.- Parameters:
name (
str)
Byte codecs of the Ring-LWE ciphertexts and values.
Format 1 (
encode_binary_ciphertext(),decode_binary_ciphertext()): thectof the MIFE / MCFE Ring-LWE crypto objects withct_format="binary"(CT_FORMATS); decryption reads it and the JSON form (ct0,ct1) alike (canonical_ring_ciphertext()).Format 2 (
encode_threshold_ciphertext(),decode_threshold_ciphertext(),threshold_ciphertext_header(),threshold_ciphertext_from_format1()): the ciphertexts of the threshold MCFE over Ring-LWE under binary public parameters. Every value is strictly belowq, so an encoding is unique.Values (
encode_values(),decode_values()):ceil(bits(q) / 8)-byte little-endian words – the polynomials of binary key shares and the binary partial decryptions.
Both formats start with b"PFRL" and a version byte (1 or 2); a reader of
one refuses the other.
- pyfe4ai.core.formats.binary.encode_binary_ciphertext(ct0, ct1, q, ring_n)[source]¶
Binary format 1 of a ciphertext with
etarowsct0andct1.b"PFRL", version 1,wb = ceil(bits(q) / 8),eta(2 bytes, little-endian),log2 ring_nand a zero byte; then the coefficients of thect0rows and ofct1,ring_neach, aswb-byte little-endian integers in[0, q).
- pyfe4ai.core.formats.binary.decode_binary_ciphertext(data, q, eta, ring_n)[source]¶
(ct0, ct1)of a format-1 ciphertext, coefficients reduced mod q.- Raises:
ValueError – If the header or the length does not match.
- Parameters:
- Return type:
- pyfe4ai.core.formats.binary.encode_threshold_ciphertext(ct0, ct1, k, q, ring_n)[source]¶
Binary format 2 of a ciphertext with batch length k.
b"PFRL", version 2,wb = ceil(bits(q) / 8),eta(2 bytes, little-endian),log2 ring_n, a zero byte andk(4 bytes, little-endian); then the firstkcoefficients of eachct0row and thering_ncoefficients ofct1, aswb-byte little-endian integers in[0, q). Decryption reads only the firstkcoefficients ofct0(coefficient-wise), whilect1enters a ring product.
- pyfe4ai.core.formats.binary.threshold_ciphertext_from_format1(data, k, q, eta, ring_n)[source]¶
Format 2 (
encode_threshold_ciphertext()) of a format-1 ciphertext whose values are below q (as this library writes them; a reader of format 2 checks that again).- Raises:
ValueError – If data is not a format-1 ciphertext of these parameters.
- Parameters:
- Return type:
- pyfe4ai.core.formats.binary.threshold_ciphertext_header(data, q, eta, ring_n)[source]¶
The batch length
kof a format-2 ciphertext of these parameters (header and length checked; the values are not).- Raises:
ValueError – If the header or the length does not match.
- Parameters:
- Return type:
- pyfe4ai.core.formats.binary.decode_values(data, q, count)[source]¶
count
ceil(bits(q) / 8)-byte little-endian integers, each strictly below q (a value>= qwould be a second encoding of one below it).- Raises:
ValueError – For another length or a value
>= q.- Parameters:
count (
int)- Return type:
- pyfe4ai.core.formats.binary.encode_values(values, q)[source]¶
Integers in
[0, q)(reduced mod q) asceil(bits(q) / 8)-byte little-endian words.- Return type:
- pyfe4ai.core.formats.binary.decode_threshold_ciphertext(data, q, eta, ring_n)[source]¶
(k, ct0, ct1)of a format-2 ciphertext:etarows ofkcoefficients andring_ncoefficients, all strictly below q.- Raises:
ValueError – If the header, the length or a value does not match.
- Parameters:
- Return type:
- pyfe4ai.core.formats.binary.canonical_ring_ciphertext(ct, q, eta, ring_n)[source]¶
Return
(k, ct0, ct1)of a BMMS21 ciphertext with coefficients in[0, q).ct holds
kand eitherct0andct1(JSON format) orct(binary format,encode_binary_ciphertext()).- Raises:
FESchemeError – Unless ct has
etapolynomialsct0and one polynomialct1ofring_ninteger coefficients each, and a batch length1 <= k <= ring_n.- Parameters:
- Return type:
The serialized objects of the LWE schemes: the ABDP15 IPFE with a seeded
public matrix (pyfe4ai.schemes.sife.lwe, pyfe4ai.schemes.mife.lwe
and the threshold pyfe4ai.schemes.mife.lwe_threshold), ALS16 FullySec
(pyfe4ai.schemes.sife.fullysec_lwe, pyfe4ai.schemes.mife.fullysec_lwe)
and the ABMPSW20 MCFE (pyfe4ai.schemes.mcfe.lwe, its FullySec,
threshold and decentralised variants; the threshold key shares and partial
decryptions are in pyfe4ai.core.formats.threshold).
Values are decimal strings unless a field says otherwise.
- class pyfe4ai.core.formats.lwe.ABDP15Record(raw)[source]¶
Bases:
RecordParameter record of the ABDP15 schemes (SIFE, MIFE and threshold MIFE LWE): the configuration it was derived for, the derived parameters and the seed of
A.Fields, in wire order:
construction– record id (SIFE_LWE_RECORD,MIFE_LWE_RECORDor a tMIFE-LWE construction id)sec_param– inteta– intlwe_n_config– the config’slwe_n(int orauto)bound_x– decimal stringbound_y– decimal stringn– int, the number of slots (MIFE)s– int, the number of servers (tMIFE)stat_param– int (tMIFE)flooding_accounting–kl(tMIFE under that accounting) (absent: ‘per-sample’)max_partial_decryptions– int (tMIFE,kl)lwe_n– intp– decimal stringq– decimal stringm– int, the rows ofAsigma_q– floatl_sigma– decimal stringsigma_f– decimal string, the flooding width (tMIFE)A_seed– 32-byte hex seed ofA
- FIELDS: ClassVar[tuple[str, ...]] = ('construction', 'sec_param', 'eta', 'lwe_n_config', 'bound_x', 'bound_y', 'n', 's', 'stat_param', 'flooding_accounting', 'max_partial_decryptions', 'lwe_n', 'p', 'q', 'm', 'sigma_q', 'l_sigma', 'sigma_f', 'A_seed')¶
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.lwe.SIFELWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE LWE (ABDP15).
Fields, in wire order:
A_seed– hex seed ofAm– intlwe_n– intgaussian_sampler– the sampler of the public keys’ noisesecurity_profile–toyorstandardp– decimal stringq– decimal stringeta– intbound_x– decimal stringbound_y– decimal stringsec_param– int
- class pyfe4ai.core.formats.lwe.MIFELWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of MIFE LWE (ABDP15 slots).
Fields, in wire order:
A_seed– hex seed ofAm– intlwe_n– intgaussian_sampler– the sampler of the public keys’ noisesecurity_profile–toyorstandardp– decimal stringq– decimal stringeta– intn– int, the number of slotsbound_x– decimal stringbound_y– decimal stringsec_param– int
- class pyfe4ai.core.formats.lwe.TMIFELWEParameters(raw)[source]¶
Bases:
MIFELWEParametersPublic parameters of the threshold MIFE over LWE.
Fields, in wire order:
A_seed– hex seed ofAm– intlwe_n– intgaussian_sampler– the sampler of the public keys’ noisesecurity_profile–toyorstandardp– decimal stringq– decimal stringeta– intn– int, the number of slotsbound_x– decimal stringbound_y– decimal stringsec_param– ints– int, the number of serverst– int, the thresholdlst_sid– the server idssigma_f– decimal string, the flooding widthsharing– the key sharing (absent: ‘shamir’)threshold_construction– construction id (optional)flooding_accounting–kl(only under that accounting) (absent: ‘per-sample’)max_partial_decryptions– int (klonly)stat_param– int (klonly)flood_tail_cut– int (klonly)
- FIELDS: ClassVar[tuple[str, ...]] = ('A_seed', 'm', 'lwe_n', 'gaussian_sampler', 'security_profile', 'p', 'q', 'eta', 'n', 'bound_x', 'bound_y', 'sec_param', 's', 't', 'lst_sid', 'sigma_f', 'sharing', 'threshold_construction', 'flooding_accounting', 'max_partial_decryptions', 'stat_param', 'flood_tail_cut')¶
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.lwe.LWEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE LWE: the public key
A S + E.Fields, in wire order:
pk–m x etamatrix
- class pyfe4ai.core.formats.lwe.MIFELWEEncryptionKey(raw)[source]¶
Bases:
LWEEncryptionKeyEncryption key of a MIFE LWE slot (the threshold MIFE adds
mac_keys).Fields, in wire order:
pk–m x etamatrixu– the slot’s pad (etavalues)mac_keys– tMIFE:{server: hex key}of the ciphertext tags
- class pyfe4ai.core.formats.lwe.SIFELWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE LWE and SIFE FullySec LWE.
Fields, in wire order:
sk_y– vectory– the weights (ints)
- class pyfe4ai.core.formats.lwe.MIFELWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of MIFE LWE and MIFE FullySec LWE (shared among the servers by the threshold MIFE).
Fields, in wire order:
sk_y–{slot: vector}z– decimal string, the pad term
- class pyfe4ai.core.formats.lwe.LWECiphertext(raw)[source]¶
Bases:
RecordCiphertext of the ABDP15 and FullySec LWE schemes (
ct0: theA-part,ct1: theetaslot values; the threshold MIFE addstags).Fields, in wire order:
ct0– vectorct1– vector ofetavaluestags– tMIFE:{server: hex HMAC}
- class pyfe4ai.core.formats.lwe.FullySecLWERecord(raw)[source]¶
Bases:
RecordParameter record of SIFE / MIFE FullySec LWE.
Fields, in wire order:
construction– record id (SIFE_FULLYSEC_LWE_RECORDor the MIFE one)sec_param– inteta– intn– int, the number of slots (MIFE)lwe_n– intm– intbound_x– decimal stringbound_y– decimal stringk– decimal stringq– decimal stringsigma_q– floatl_sigma_q– decimal stringsigma1– floatl_sigma1– decimal stringsigma2– floatl_sigma2– decimal stringA_seed– 32-byte hex seed ofA
- class pyfe4ai.core.formats.lwe.FullySecLWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE / MIFE FullySec LWE (
Aexpanded).Fields, in wire order:
A–m x lwe_nmatrixk– decimal stringq– decimal stringm– inteta– intn– int, the number of slots (MIFE)lwe_n– intbound_x– decimal stringbound_y– decimal stringsigma_q– floatsigma1– floatsigma2– floatsec_param– int
- class pyfe4ai.core.formats.lwe.MCFELWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of the MCFE over LWE (ABMPSW20 Fig. 4; also FullySec).
Fields, in wire order:
q– decimal stringq0– int, the rounding modulusK– intdelta– decimal stringbound_ip– int, the decoding boundn0– intm0– intsecurity–selectiveoradaptiveeta– intn– int, the number of clientslwe_n– intbound_x– intbound_y– intstat_param– intsec_param– intgaussian_sampler– the sampler of the keyssecurity_profile–toyorstandardlabel_hash– label hash mode (absent: ‘shake256-wide’)
- class pyfe4ai.core.formats.lwe.TMCFELWEParameters(raw)[source]¶
Bases:
MCFELWEParametersPublic parameters of the threshold MCFE over LWE.
Fields, in wire order:
q– decimal stringq0– int, the rounding modulusK– intdelta– decimal stringbound_ip– int, the decoding boundn0– intm0– intsecurity–selectiveoradaptiveeta– intn– int, the number of clientslwe_n– intbound_x– intbound_y– intstat_param– intsec_param– intgaussian_sampler– the sampler of the keyssecurity_profile–toyorstandardlabel_hash– label hash mode (absent: ‘shake256-wide’)s– int, the number of serverst– int, the thresholdlst_sid– the server idssigma_f– decimal string, the flooding widthsharing– the key sharing (absent: ‘shamir’)threshold_construction– construction id (optional)
- FIELDS: ClassVar[tuple[str, ...]] = ('q', 'q0', 'K', 'delta', 'bound_ip', 'n0', 'm0', 'security', 'eta', 'n', 'lwe_n', 'bound_x', 'bound_y', 'stat_param', 'sec_param', 'gaussian_sampler', 'security_profile', 'label_hash', 's', 't', 'lst_sid', 'sigma_f', 'sharing', 'threshold_construction')¶
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.lwe.DecentralizedLWEParameters(raw)[source]¶
Bases:
MCFELWEParametersPublic parameters of the decentralised MCFE over LWE (Fig. 14).
Fields, in wire order:
q– decimal stringq0– int, the rounding modulusK– intdelta– decimal stringbound_ip– int, the decoding boundn0– intm0– intsecurity–selectiveoradaptiveeta– intn– int, the number of clientslwe_n– intbound_x– intbound_y– intstat_param– intsec_param– intgaussian_sampler– the sampler of the keyssecurity_profile–toyorstandardlabel_hash– label hash mode (absent: ‘shake256-wide’)n2_mod– decimal string, the DCR modulus of the key derivationlst_nid– the client idscontribution_bound– decimal string
- FIELDS: ClassVar[tuple[str, ...]] = ('q', 'q0', 'K', 'delta', 'bound_ip', 'n0', 'm0', 'security', 'eta', 'n', 'lwe_n', 'bound_x', 'bound_y', 'stat_param', 'sec_param', 'gaussian_sampler', 'security_profile', 'label_hash', 'n2_mod', 'lst_nid', 'contribution_bound')¶
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.lwe.DecentralizedLWERecord(raw)[source]¶
Bases:
RecordParameter record of the decentralised MCFE over LWE (the DCR modulus only).
Fields, in wire order:
construction– record id (DMCFE_LWE_RECORD)n2_prime_bits– intn2_mod– decimal string
- class pyfe4ai.core.formats.lwe.MCFELWEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of an MCFE LWE client (the decentralised MCFE adds
s2).Fields, in wire order:
z– per slot,n0 + m0decimal stringslabel_hash– label hash mode (absent: ‘shake256-wide’)s2– dMCFE: the client’s key of the key derivation (decimal strings)
- class pyfe4ai.core.formats.lwe.MCFELWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of the MCFE over LWE (also the combined key of the decentralised variant).
Fields, in wire order:
sk_y–n0 + m0decimal strings
- class pyfe4ai.core.formats.lwe.MCFELWECiphertext(raw)[source]¶
Bases:
RecordCiphertext of the MCFE over LWE: one element of
Z_q0per slot (ints) and the label hash code (none forshake256-wide; in an ndarray layer only its first element carries it).Fields, in wire order:
c– intslabel_hash– int code; absent, code 0 (versions <= 0.3.0) for a single ciphertext and the layer’s code for an element of an ndarray layer (optional)
The serialized objects of the Ring-LWE schemes: SIFE (pyfe4ai.schemes.sife.ring_lwe),
SIFE FullySec (pyfe4ai.schemes.sife.fullysec_ring_lwe), and the
MIFE / MCFE family over BMMS21 (pyfe4ai.schemes.mife.ring_lwe,
pyfe4ai.schemes.mcfe.ring_lwe, its decentralised and threshold
variants; the threshold key shares and partial decryptions are in
pyfe4ai.core.formats.threshold).
Values are decimal strings unless a field says otherwise; a polynomial is a
list of ring_n values, or (binary formats) bytes of
ceil(bits(q) / 8)-byte words (pyfe4ai.core.formats.binary).
- class pyfe4ai.core.formats.ring_lwe.SIFERingLWERecord(raw)[source]¶
Bases:
RecordParameter record of SIFE Ring-LWE (
SIFE_RING_LWE/param.json).Fields, in wire order:
param_version– record id (SIFE_RING_LWE_RECORD)sec_param– inteta– intring_n– intbound_x– decimal stringbound_y– decimal stringp– decimal stringq– decimal stringsigma1– floatsigma2– floatsigma3– floatA_seed– hex seed ofa
- class pyfe4ai.core.formats.ring_lwe.SIFERingLWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE Ring-LWE.
Fields, in wire order:
A– the polynomiala(expanded)p– decimal stringq– decimal stringeta– intring_n– intbound_x– decimal stringbound_y– decimal stringsigma1– floatsigma2– floatsigma3– floatsec_param– intgaussian_sampler–facctorroundedsecurity_profile–toyorstandard
- class pyfe4ai.core.formats.ring_lwe.SIFERingLWEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE Ring-LWE.
Fields, in wire order:
pk–etapolynomials
- class pyfe4ai.core.formats.ring_lwe.SIFERingLWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE Ring-LWE.
Fields, in wire order:
sk_y– polynomialy– the weights (ints)
- class pyfe4ai.core.formats.ring_lwe.SIFERingLWECiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE Ring-LWE (
ct0: theetaslot polynomialspk_i r + f_i + Delta x_i;ct1:a r + e).Fields, in wire order:
ct0–etapolynomialsct1– polynomialk– int, the batch length (columns of the plaintext)
- class pyfe4ai.core.formats.ring_lwe.FullySecRingLWERecord(raw)[source]¶
Bases:
RecordParameter record of SIFE FullySec Ring-LWE (
SIFE_FULLYSEC_RING_LWE/param.json).Fields, in wire order:
param_version– record id (SIFE_FULLYSEC_RING_LWE_RECORD, or the packed one)sec_param– inteta– intbound_x– decimal stringbound_y– decimal stringring_n_config– the config’sring_n(int,autoor null)m_config– the config’smprofile– security profilering_n– intm– intp– decimal stringq– decimal stringa_seed– hex seed ofasigma– floatsigma_lhl– floatsigma1– floatsigma2– floatsigma3– floatndarray_layout–packed(only for that layout) (absent: ‘elementwise’)
- class pyfe4ai.core.formats.ring_lwe.FullySecRingLWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE FullySec Ring-LWE.
Fields, in wire order:
a–mpolynomialsp– decimal stringq– decimal stringring_n– intm– inteta– intbound_x– decimal stringbound_y– decimal stringsigma2– floatsigma3– floatsec_param– intgaussian_sampler–facctorroundedsecurity_profile–toyorstandardndarray_layout–packed(only for that layout) (absent: ‘elementwise’)
- class pyfe4ai.core.formats.ring_lwe.FullySecRingLWEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE FullySec Ring-LWE.
Fields, in wire order:
pk–etapolynomials
- class pyfe4ai.core.formats.ring_lwe.FullySecRingLWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE FullySec Ring-LWE.
Fields, in wire order:
sk_y–mpolynomialsy– the weights (ints)
- class pyfe4ai.core.formats.ring_lwe.FullySecRingLWECiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE FullySec Ring-LWE (
ct0:a r + f0;ct: theetaslots;k: the batch length of a packed ciphertext).Fields, in wire order:
ct0–mpolynomialsct–etapolynomialsk– int (packed layout only)
- class pyfe4ai.core.formats.ring_lwe.FullySecRingLWELayer(raw)[source]¶
Bases:
RecordOne packed ndarray layer of SIFE FullySec Ring-LWE (
ndarray_layout = "packed"): chunkjholds elementsj ring_nonward.Fields, in wire order:
shape– list of intsfirst_chunk– int, the chunks before this layerchunks– packed ciphertexts (FullySecRingLWECiphertextwithk)
- class pyfe4ai.core.formats.ring_lwe.RingLWERecord(raw)[source]¶
Bases:
RecordParameter record of the MIFE / MCFE Ring-LWE family (
param.json;param-rns.jsonfor an RNS modulus). The threshold MCFE adds the fields ofThresholdRingLWERecord.Fields, in wire order:
construction– record id (RING_LWE_RECORD)sec_param– inteta– intn– int, the number of slotsring_n– intbound_x– decimal stringbound_y– decimal stringp– decimal stringq– decimal string (the threshold MCFE’s flooded modulus)sigma1– floatsigma2– floatsigma3– floatA_seed– hex seed ofaring_modulus–rns(only for that modulus) (absent: ‘prime’)q_factors– the factors of an RNSq(decimal strings) (optional)
- class pyfe4ai.core.formats.ring_lwe.ThresholdRingLWERecord(raw)[source]¶
Bases:
RingLWERecordParameter record of the threshold MCFE over Ring-LWE.
Fields, in wire order:
construction– record id (RING_LWE_RECORD)sec_param– inteta– intn– int, the number of slotsring_n– intbound_x– decimal stringbound_y– decimal stringp– decimal stringq– decimal string (the threshold MCFE’s flooded modulus)sigma1– floatsigma2– floatsigma3– floatA_seed– hex seed ofaring_modulus–rns(only for that modulus) (absent: ‘prime’)q_factors– the factors of an RNSq(decimal strings) (optional)threshold_construction– construction id (TMCFE_RING_LWE_CONSTRUCTION_IDS)s– int, the number of serversstat_param– intflooding_accounting–kl(only under that accounting) (absent: ‘per-sample’)max_partial_decryptions– int (klonly) (optional)flooding–uniform(uniform flooding only) (absent: ‘gaussian’)flood_bits– int, the uniform flooding’s widthsigma_f– decimal string, the Gaussian flooding’s width
- FIELDS: ClassVar[tuple[str, ...]] = ('construction', 'sec_param', 'eta', 'n', 'ring_n', 'bound_x', 'bound_y', 'p', 'q', 'sigma1', 'sigma2', 'sigma3', 'A_seed', 'ring_modulus', 'q_factors', 'threshold_construction', 's', 'stat_param', 'flooding_accounting', 'max_partial_decryptions', 'flooding', 'flood_bits', 'sigma_f')¶
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.ring_lwe.MIFERingLWEParameters(raw)[source]¶
Bases:
RecordPublic parameters of MIFE Ring-LWE.
Fields, in wire order:
A– the polynomiala(expanded)p– decimal stringq– decimal stringeta– intn– int, the number of slotsring_n– intbound_x– decimal stringbound_y– decimal stringsigma1– floatsigma2– floatsigma3– floatsec_param– intgaussian_sampler–facctorroundedsecurity_profile–toyorstandardq_factors– the factors of an RNSq(decimal strings; RNS only) (optional)
- class pyfe4ai.core.formats.ring_lwe.MCFERingLWEParameters(raw)[source]¶
Bases:
MIFERingLWEParametersPublic parameters of MCFE Ring-LWE.
Fields, in wire order:
A– the polynomiala(expanded)p– decimal stringq– decimal stringeta– intn– int, the number of slotsring_n– intbound_x– decimal stringbound_y– decimal stringsigma1– floatsigma2– floatsigma3– floatsec_param– intgaussian_sampler–facctorroundedsecurity_profile–toyorstandardq_factors– the factors of an RNSq(decimal strings; RNS only) (optional)label_hash– label hash mode (LABEL_HASHES) (absent: ‘shake256-wide’)
- class pyfe4ai.core.formats.ring_lwe.DecentralizedRingLWEParameters(raw)[source]¶
Bases:
MCFERingLWEParametersPublic parameters of the decentralised MCFE over Ring-LWE.
Fields, in wire order:
A– the polynomiala(expanded)p– decimal stringq– decimal stringeta– intn– int, the number of slotsring_n– intbound_x– decimal stringbound_y– decimal stringsigma1– floatsigma2– floatsigma3– floatsec_param– intgaussian_sampler–facctorroundedsecurity_profile–toyorstandardq_factors– the factors of an RNSq(decimal strings; RNS only) (optional)label_hash– label hash mode (LABEL_HASHES) (absent: ‘shake256-wide’)lst_nid– the client ids
- class pyfe4ai.core.formats.ring_lwe.ThresholdRingLWEParameters(raw)[source]¶
Bases:
MCFERingLWEParametersPublic parameters of the threshold MCFE over Ring-LWE.
Fields, in wire order:
A– the polynomiala(expanded)p– decimal stringq– decimal stringeta– intn– int, the number of slotsring_n– intbound_x– decimal stringbound_y– decimal stringsigma1– floatsigma2– floatsigma3– floatsec_param– intgaussian_sampler–facctorroundedsecurity_profile–toyorstandardq_factors– the factors of an RNSq(decimal strings; RNS only) (optional)label_hash– label hash mode (LABEL_HASHES) (absent: ‘shake256-wide’)s– int, the number of serverst– int, the thresholdlst_sid– the server idsflooding–uniformorgaussian(absent: ‘gaussian’)sharing–shamir,replicatedorreplicated-seeded(absent: ‘shamir’)threshold_construction– construction id (optional)flood_bits– int, the uniform flooding’s widthsigma_f– decimal string, the Gaussian flooding’s widthct_format–binary(only for that format) (absent: ‘json’)flooding_accounting–kl(only under that accounting) (absent: ‘per-sample’)max_partial_decryptions– int (klonly)stat_param– int (klonly)flood_tail_cut– int (klonly)
- FIELDS: ClassVar[tuple[str, ...]] = ('A', 'p', 'q', 'eta', 'n', 'ring_n', 'bound_x', 'bound_y', 'sigma1', 'sigma2', 'sigma3', 'sec_param', 'gaussian_sampler', 'security_profile', 'q_factors', 'label_hash', 's', 't', 'lst_sid', 'flooding', 'sharing', 'threshold_construction', 'flood_bits', 'sigma_f', 'ct_format', 'flooding_accounting', 'max_partial_decryptions', 'stat_param', 'flood_tail_cut')¶
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.ring_lwe.MIFERingLWEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of a MIFE Ring-LWE slot.
Fields, in wire order:
pk–etapolynomialsu–etapolynomials, the slot’s pad
- class pyfe4ai.core.formats.ring_lwe.MCFERingLWEEncryptionKey(raw)[source]¶
Bases:
MIFERingLWEEncryptionKeyEncryption key of an MCFE Ring-LWE client.
Fields, in wire order:
pk–etapolynomialsu–etapolynomials, the slot’s padu_prime– hex secret of the label padslabel_hash– label hash mode (absent: ‘shake256-wide’)
- class pyfe4ai.core.formats.ring_lwe.DecentralizedRingLWEEncryptionKey(raw)[source]¶
Bases:
MCFERingLWEEncryptionKeyEncryption key of a client of the decentralised MCFE over Ring-LWE.
Fields, in wire order:
pk–etapolynomialsu–etapolynomials, the slot’s padu_prime– hex secret of the label padslabel_hash– label hash mode (absent: ‘shake256-wide’)s–etapolynomials, the client’s IPFE secretpair_keys–{other client: hex key}
- class pyfe4ai.core.formats.ring_lwe.ThresholdRingLWEEncryptionKey(raw)[source]¶
Bases:
MCFERingLWEEncryptionKeyEncryption key of a client of the threshold MCFE over Ring-LWE.
Fields, in wire order:
pk–etapolynomialsu–etapolynomials, the slot’s padu_prime– hex secret of the label padslabel_hash– label hash mode (absent: ‘shake256-wide’)mac_keys–{server: hex key}of the ciphertext tags
- class pyfe4ai.core.formats.ring_lwe.MIFERingLWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of MIFE Ring-LWE.
Fields, in wire order:
sk_y–{client: polynomial}z– polynomial
- class pyfe4ai.core.formats.ring_lwe.MCFERingLWEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of MCFE Ring-LWE, bound to a label (also the combined key of the decentralised variant).
Fields, in wire order:
sk_y–{client: polynomial}z– polynomial, the term of the label itselfz_chunks– polynomials, the terms of the chunk labelslabel– str, the labellabel_hash– label hash mode (absent: ‘shake256-wide’)
Bases:
RecordA client’s share of a functional key of the decentralised MCFE over Ring-LWE (
derive_function_decryption_key_share()).Fields, in wire order:
sk_y– polynomial, the client’s slotz– polynomialz_chunks– polynomialslabel– strnid– the client id (str or int)weights_id– hex digest of the weightslabel_hash– label hash mode (absent: ‘shake256-wide’)
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.ring_lwe.RingLWECiphertext(raw)[source]¶
Bases:
RecordCiphertext of the MIFE / MCFE Ring-LWE family: JSON (
ct0,ct1) or binary (ct: format 1, or format 2 under binary threshold public parameters), the batch length, the label hash code (MCFE, none forshake256-wide) and the threshold MCFE’s tags.Fields, in wire order:
ct0–etapolynomials (JSON)ct1– polynomial (JSON)ct– bytes (binary formats)k– int, the batch lengthlabel_hash– int code (LABEL_HASH_CODES); absent, code 0 (versions <= 0.3.0) for a single ciphertext and the layer’s code for a chunk of a packed layer (optional)tags–{server: hex HMAC}(threshold MCFE)
- class pyfe4ai.core.formats.ring_lwe.RingLWELayer(raw)[source]¶
Bases:
RecordOne layer of packed ndarray ciphertexts (MCFE Ring-LWE; SIFE FullySec Ring-LWE’s packed layer has no
label_hash): chunkjholds elementsj ring_nonward, under the chunk labelfirst_chunk + j.Fields, in wire order:
shape– list of intsfirst_chunk– int, the chunks before this layerchunks– ciphertexts (RingLWECiphertext)label_hash– int code, the layer’s (absent: 0)
The serialized objects of the discrete-log and DCR schemes: DDH over
Z_p^* (pyfe4ai.schemes.sife.ddh, ddh_dynamic,
pyfe4ai.schemes.mife.ddh, pyfe4ai.schemes.mcfe.ddh and their
threshold and decentralised variants), DDH over ristretto255, Damgard /
MDDH and Paillier (DCR), and the key shares of the decentralised MCFE key
derivation (ABMPSW20 Fig. 14) that the decentralised DDH, DCR and LWE
schemes share. The threshold key shares and partial decryptions are in
pyfe4ai.core.formats.threshold.
Values are decimal strings unless a field says otherwise; points of ristretto255 are 64-character hex strings.
- class pyfe4ai.core.formats.dl.DLGroupRecord(raw)[source]¶
Bases:
RecordThe group of a DDH or Damgard parameter record (
p = r q + 1).Fields, in wire order:
p– decimal string, the modulusq– decimal string, the subgroup orderr– decimal string, the cofactor (DDH records: 2)
- class pyfe4ai.core.formats.dl.DDHRecord(raw)[source]¶
Bases:
RecordParameter record of the DDH schemes over
Z_p^*(SIFE, MIFE, MCFE and their threshold and decentralised variants).Fields, in wire order:
sec_param– int, the bits ofpg– decimal string, the generatoreta– int (or per client)group–DLGroupRecordn– int, the number of clients (MIFE, MCFE)s– the number of servers (MIFE, MCFE; tMCFE)t– int, the threshold (tMCFE)construction– record id (tMCFETMCFE_DDH_RECORD, dMCFEDMCFE_DDH_RECORD)n2_prime_bits– int (dMCFE)n2_mod– decimal string, the DCR modulus of the key derivation (dMCFE)
- class pyfe4ai.core.formats.dl.DamgardRecord(raw)[source]¶
Bases:
RecordParameter record of SIFE and MIFE Damgard.
Fields, in wire order:
sec_param– inteta– intmodulus_length– intbound– intgroup–DLGroupRecord(pandq)g– decimal stringh_seed– hex seed ofhn– int, the number of slots (MIFE)
- class pyfe4ai.core.formats.dl.MCFEDamgardRecord(raw)[source]¶
Bases:
RecordParameter record of MCFE Damgard (MDDH).
Fields, in wire order:
construction– record id (MCFE_DAMGARD_RECORD)modulus_length– intp– decimal stringq– decimal stringg– decimal string
- class pyfe4ai.core.formats.dl.SIFEPaillierRecord(raw)[source]¶
Bases:
RecordParameter record of SIFE Paillier (the factors are never stored).
Fields, in wire order:
sec_param– inteta– intbit_length– intbound_x– intbound_y– intparam_format– record format (PAILLIER_RECORD)n– decimal string, the modulusNn_square– decimal stringg_seed– hex seed ofg
- class pyfe4ai.core.formats.dl.MIFEPaillierRecord(raw)[source]¶
Bases:
RecordParameter record of MIFE Paillier.
Fields, in wire order:
sec_param– inteta– intn– int, the number of slotsbit_length– intbound_x– intbound_y– intparam_format– record format (PAILLIER_RECORD)n_mod– decimal string, the modulusNn_square– decimal stringg_seed– hex seed ofg
- class pyfe4ai.core.formats.dl.MCFEPaillierRecord(raw)[source]¶
Bases:
RecordParameter record of MCFE Paillier and of the decentralised MCFE over DCR.
Fields, in wire order:
construction– record id (MCFE_PAILLIER_RECORDor the dMCFE one)bit_length– intn2_prime_bits– int (dMCFE)n_mod– decimal string, the modulusNn2_mod– decimal string, the DCR modulus of the key derivation (dMCFE)
- class pyfe4ai.core.formats.dl.SIFEDDHParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE DDH.
Fields, in wire order:
g– decimal stringp– decimal stringeta– intsec_param– int
- class pyfe4ai.core.formats.dl.SIFEDDHEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE DDH:
g^{s_i}.Fields, in wire order:
gs–etadecimal strings
- class pyfe4ai.core.formats.dl.SIFEDDHFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE DDH (
ddh_dynamicaddssize).Fields, in wire order:
z– decimal string,<s, y> mod qy– the weights (ints)size– int, the number of weights (ddh_dynamic)
- class pyfe4ai.core.formats.dl.SIFEDDHCiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE DDH (also SIFE DDH over ristretto255, with points).
Fields, in wire order:
ct0–g^rct1–g^{x_i} gs_i^r
- class pyfe4ai.core.formats.dl.MIFEDDHParameters(raw)[source]¶
Bases:
RecordPublic parameters of MIFE DDH (the threshold MIFE adds
t,sandlst_sid).Fields, in wire order:
construction– public id (MIFE_DDH_CONSTRUCTION; not checked)g– decimal stringp– decimal stringq– decimal stringn– inteta– int (or per client)lst_nid– the client idssec_param– intt– int (tMIFE)s– int (tMIFE)lst_sid– the server ids (tMIFE)
- class pyfe4ai.core.formats.dl.MIFEDDHEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of a MIFE DDH slot (ristretto255: points and scalars).
Fields, in wire order:
h–g^{s_j}u– the slot’s pad
- class pyfe4ai.core.formats.dl.MIFEDDHFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of MIFE DDH (also over ristretto255).
Fields, in wire order:
d–{slot: <s_i, y_i>}z– the pad termweights_id– hex digest of the weights
- class pyfe4ai.core.formats.dl.MIFEDDHCiphertext(raw)[source]¶
Bases:
RecordCiphertext of MIFE DDH (also over ristretto255).
Fields, in wire order:
t–g^rc– the slot values
- class pyfe4ai.core.formats.dl.MCFEDDHParameters(raw)[source]¶
Bases:
RecordPublic parameters of MCFE DDH (the decentralised MCFE adds its fields).
Fields, in wire order:
g– decimal stringp– decimal stringn– inteta– int (or per client)sec_param– intn2_mod– decimal string (dMCFE)lst_nid– the client ids (dMCFE)contribution_bound– decimal string (dMCFE)mask_bits– int (dMCFE)
- class pyfe4ai.core.formats.dl.TMCFEDDHParameters(raw)[source]¶
Bases:
RecordPublic parameters of the threshold MCFE over DDH.
Fields, in wire order:
p– decimal stringg– decimal stringeta– ints– intt– intn– intsec_param– int
- class pyfe4ai.core.formats.dl.MCFEDDHEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of an MCFE DDH client (also MCFE Damgard, Paillier and ristretto255; the decentralised MCFE adds
s2andmask_key).Fields, in wire order:
s– per slot, the client’s secrets2– dMCFE: the client’s key of the key derivationmask_key– dMCFE DDH: hex key of the carry masks
- class pyfe4ai.core.formats.dl.PreparedKey(raw)[source]¶
Bases:
RecordA functional key of the element-wise MCFE schemes as
prepare_key()returns it: the key’s fields, thenkey_terms(an in-process object, never serialised).Fields, in wire order:
key_terms– the prepared key terms (in process only)
- class pyfe4ai.core.formats.dl.MCFEDDHFunctionalKey(raw)[source]¶
Bases:
PreparedKeyFunctional key of MCFE DDH and MCFE Damgard.
Fields, in wire order:
d– decimal stringskey_terms– the prepared key terms (in process only)
- class pyfe4ai.core.formats.dl.MCFEPaillierFunctionalKey(raw)[source]¶
Bases:
PreparedKeyFunctional key of MCFE Paillier and of the decentralised MCFE over DCR.
Fields, in wire order:
k– decimal string (over Z)key_terms– the prepared key terms (in process only)
- class pyfe4ai.core.formats.dl.MCFEDDHCiphertext(raw)[source]¶
Bases:
RecordCiphertext of the element-wise MCFE schemes (DDH, ristretto255, Damgard, Paillier): one value per slot; the threshold MCFE adds the encoded label.
Fields, in wire order:
c– one value per slotlabel– tMCFE DDH: the encoded label
- class pyfe4ai.core.formats.dl.RistrettoParameters(raw)[source]¶
Bases:
RecordPublic parameters of the ristretto255 schemes (MIFE adds its id and clients).
Fields, in wire order:
construction– MIFE: public id (not checked)group–ristretto255n– int (MIFE, MCFE)eta– int (or per client)lst_nid– the client ids (MIFE)
- class pyfe4ai.core.formats.dl.SIFERistrettoEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE DDH over ristretto255.
Fields, in wire order:
h–etapoints
- class pyfe4ai.core.formats.dl.SIFEDamgardParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE and MIFE Damgard.
Fields, in wire order:
p– decimal stringq– decimal stringg– decimal stringh– decimal stringeta– intn– int (MIFE)bound– intsec_param– intmodulus_length– int
- class pyfe4ai.core.formats.dl.DamgardEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE / MIFE Damgard (MIFE adds the pad
u).Fields, in wire order:
pk– decimal stringsu– MIFE: the slot’s pad
- class pyfe4ai.core.formats.dl.SIFEDamgardFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE Damgard.
Fields, in wire order:
k1– decimal stringk2– decimal stringy– the weights (ints)
- class pyfe4ai.core.formats.dl.MIFEDamgardFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of MIFE Damgard.
Fields, in wire order:
k1–{slot: decimal string}k2–{slot: decimal string}z– decimal string, the pad term
- class pyfe4ai.core.formats.dl.DamgardCiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE / MIFE Damgard.
Fields, in wire order:
c–g^rd–h^re– the slot values
- class pyfe4ai.core.formats.dl.MCFEDamgardParameters(raw)[source]¶
Bases:
RecordPublic parameters of MCFE Damgard (MDDH).
Fields, in wire order:
p– decimal stringq– decimal stringg– decimal stringmddh_k– inteta– intn– intbound– intsec_param– intmodulus_length– int
- class pyfe4ai.core.formats.dl.SIFEPaillierParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE Paillier.
Fields, in wire order:
n– decimal string, the modulusNn_square– decimal stringg– decimal stringeta– intsec_param– intbit_length– intbound_x– intbound_y– int
- class pyfe4ai.core.formats.dl.MIFEPaillierParameters(raw)[source]¶
Bases:
RecordPublic parameters of MIFE Paillier.
Fields, in wire order:
n_mod– decimal string, the modulusNn_square– decimal stringg– decimal stringeta– intn– int, the number of slotssec_param– intbit_length– intbound_x– intbound_y– int
- class pyfe4ai.core.formats.dl.MCFEPaillierParameters(raw)[source]¶
Bases:
RecordPublic parameters of MCFE Paillier (the decentralised MCFE adds its fields).
Fields, in wire order:
n_mod– decimal string, the modulusNn_square– decimal stringeta– intn– intsec_param– intbit_length– intbound_x– intbound_y– intn2_mod– decimal string (dMCFE)lst_nid– the client ids (dMCFE)contribution_bound– decimal string (dMCFE)
- class pyfe4ai.core.formats.dl.PaillierEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE / MIFE Paillier (MIFE adds the pad
u).Fields, in wire order:
pk– decimal strings inZ_{N^2}u– MIFE: the slot’s pad
- class pyfe4ai.core.formats.dl.SIFEPaillierFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE Paillier.
Fields, in wire order:
k– decimal string,<s, y>over Z
- class pyfe4ai.core.formats.dl.MIFEPaillierFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of MIFE Paillier.
Fields, in wire order:
k–{slot: decimal string}over Zz– decimal string, the pad term mod N
- class pyfe4ai.core.formats.dl.PaillierCiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE / MIFE Paillier.
Fields, in wire order:
ct0–g^rct1– the slot values
Bases:
RecordA client’s share of a functional key of the decentralised MCFE (
pyfe4ai.schemes.mcfe.decentralize): its contribution encrypted under the MCFE2 key.Fields, in wire order:
c– decimal strings, the MCFE2 ciphertexts of the contributionnid– the client id (str or int)weights_id– hex digest of the weights
Field names in wire order (set for every subclass).
The serialized objects of the pairing schemes: function-hiding IPFE
(pyfe4ai.schemes.sife.fh_ipe_pairing), partially function-hiding IPFE
(pyfe4ai.schemes.sife.part_fh_ipe_pairing), the function-hiding MIFE
(pyfe4ai.schemes.mife.fh_ipe_pairing,
pyfe4ai.schemes.mife.fh_multi_ipe_pairing), the function-hiding MCFE
(pyfe4ai.schemes.mcfe.fh_multi_ipe_pairing and its threshold and
decentralised variants; the threshold key shares and partial decryptions are
in pyfe4ai.core.formats.threshold) and the quadratic schemes
(pyfe4ai.schemes.quadratic).
Group elements are serialised strings (group.serialize(e).decode("utf-8"));
scalars are decimal strings unless a field says otherwise.
- class pyfe4ai.core.formats.pairing.SIFEFHIPERecord(raw)[source]¶
Bases:
RecordParameter record of SIFE FH-IPE (the configuration only; no group elements).
Fields, in wire order:
sec_param– inteta– intbound_x– decimal stringbound_y– decimal stringpairing_group_param– the pairing group
- class pyfe4ai.core.formats.pairing.SIFEFHIPEParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE FH-IPE.
Fields, in wire order:
eta– intbound_x– decimal stringbound_y– decimal stringpairing_group_param– the pairing group
- class pyfe4ai.core.formats.pairing.SIFEFHIPEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of SIFE FH-IPE (equivalent to the master secret key).
Fields, in wire order:
g2– G2b_star–(eta + 2) x (eta + 2)matrix of decimal strings
- class pyfe4ai.core.formats.pairing.SIFEFHIPEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE FH-IPE (no weights: function hiding).
Fields, in wire order:
k1– G1k2–eta + 2G1 elements
- class pyfe4ai.core.formats.pairing.SIFEFHIPECiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE FH-IPE.
Fields, in wire order:
c1– G2c2–eta + 2G2 elements
- class pyfe4ai.core.formats.pairing.PartFHIPERecord(raw)[source]¶
Bases:
RecordParameter record of SIFE partially FH-IPE (the configuration only).
Fields, in wire order:
sec_param– inteta– intbound– decimal stringsubspace_dim– int,kcoeff_bound– decimal stringpairing_group_param– the pairing group
- class pyfe4ai.core.formats.pairing.PartFHIPEParameters(raw)[source]¶
Bases:
RecordPublic parameters of SIFE partially FH-IPE (the public key included).
Fields, in wire order:
eta– intbound– decimal stringsubspace_dim– int,kcoeff_bound– decimal stringpairing_group_param– the pairing groupg1– G1g2– G2a– two G1 elementsua–eta + 2G1 elementsvt_m–2 x kmatrix of decimal stringsm–eta x kmatrix of decimal strings
- class pyfe4ai.core.formats.pairing.PartFHIPEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SIFE partially FH-IPE.
Fields, in wire order:
k–eta + 4G2 elements
- class pyfe4ai.core.formats.pairing.PartFHIPECiphertext(raw)[source]¶
Bases:
RecordCiphertext of SIFE partially FH-IPE (
EncandEnc').Fields, in wire order:
ct–eta + 4G1 elements
- class pyfe4ai.core.formats.pairing.FHParameters(raw)[source]¶
Bases:
RecordPublic parameters of the function-hiding MIFE (ACFGU18) and MCFE (AGT21b).
Fields, in wire order:
pairing_group_param– the pairing groupg1– G1g2– G2eta– intn– intlst_nid– the client idsbound_x– intbound_y– intsec_param– int
- class pyfe4ai.core.formats.pairing.TMCFEFHParameters(raw)[source]¶
Bases:
FHParametersPublic parameters of the threshold FH-MCFE.
Fields, in wire order:
pairing_group_param– the pairing groupg1– G1g2– G2eta– intn– intlst_nid– the client idsbound_x– intbound_y– intsec_param– ints– intt– intlst_sid– the server ids
- class pyfe4ai.core.formats.pairing.FHMasterKey(raw)[source]¶
Bases:
RecordA slot’s FH-IPFE master key as a client holds it (
imsk; integers as decimal strings). Clients of the MIFE and MCFE get it withouta_out, which only key generation needs.Fields, in wire order:
a_in– two decimal stringsu– rows of two decimal stringsw– rows of two decimal stringsz– decimal stringa_out– two decimal strings (decentralised MCFE only)
- class pyfe4ai.core.formats.pairing.FHClientKey(raw)[source]¶
Bases:
RecordEncryption key of a client of the function-hiding MIFE / MCFE.
Fields, in wire order:
imsk–FHMasterKeymac_keys– tMCFE:{server: hex key}of the ciphertext tagst_tilde– dMCFE: the client’s share of zero (decimal string)seed– dMCFE: 64-char hex seed of the key derivation
- class pyfe4ai.core.formats.pairing.MIFEFHIPEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of the function-hiding MIFE (ACFGU18 Fig. 12).
Fields, in wire order:
dk–{slot: FH-IPFE key (G2 elements)}z– GT,[r sum z_i]_Tkey_id– 32-char hex, random
- class pyfe4ai.core.formats.pairing.FHKeyEntry(raw)[source]¶
Bases:
RecordA client’s part of a functional key of the FH-MCFE (also a client’s key share of the decentralised FH-MCFE, which adds
nidandtag_f).Fields, in wire order:
k– G2 elementsz– GTnid– dMCFE: the clienttag_f– dMCFE: the function tag
- class pyfe4ai.core.formats.pairing.MCFEFHFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of the FH-MCFE (the decentralised MCFE’s combined key has
tag_fand nokey_id).Fields, in wire order:
dk–{client: FHKeyEntry}key_id– 32-char hex, randomtag_f– dMCFE: the function tag
- class pyfe4ai.core.formats.pairing.FHCiphertext(raw)[source]¶
Bases:
RecordCiphertext of the function-hiding MIFE / MCFE schemes (the threshold FH-MCFE adds the encoded label and the server tags).
Fields, in wire order:
ct– G1 elementslabel– tMCFE: the encoded labeltags– tMCFE:{server: hex HMAC}
- class pyfe4ai.core.formats.pairing.MIFEFHMultiIPERecord(raw)[source]¶
Bases:
RecordParameter record of the full-hiding MIFE (DOT18; the configuration only).
Fields, in wire order:
sec_param– intsec_level– inteta– intn– intbound_x– decimal stringbound_y– decimal stringpairing_group_param– the pairing group
- class pyfe4ai.core.formats.pairing.MIFEFHMultiIPEParameters(raw)[source]¶
Bases:
RecordPublic parameters of the full-hiding MIFE (DOT18).
Fields, in wire order:
sec_level– inteta– intn– intlst_nid– the client idsbound_x– decimal stringbound_y– decimal stringpairing_group_param– the pairing groupg1– G1g2– G2pub– GT
- class pyfe4ai.core.formats.pairing.MIFEFHMultiIPEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key of a slot of the full-hiding MIFE.
Fields, in wire order:
bhat–(eta + k + 1) x dimmatrix of decimal strings
- class pyfe4ai.core.formats.pairing.MIFEFHMultiIPEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of the full-hiding MIFE.
Fields, in wire order:
dk–{slot: G2 elements}
- class pyfe4ai.core.formats.pairing.QuadIPFEPublicKey(raw)[source]¶
Bases:
RecordThe public key of the IPFE inside Quad (Gay20 Fig. 4).
Fields, in wire order:
a– two G1 elementsua– G1 elementsvt_m– rows of G1 elementsm– rows of G1 elements
- class pyfe4ai.core.formats.pairing.QuadParameters(raw)[source]¶
Bases:
RecordPublic parameters (the public key) of Quad.
Fields, in wire order:
pairing_group_param– the pairing groupn– intm– intbound– intsec_param– intg1– G1g2– G2ua–nG1 elementsvb–m x 2G2 elementsipfe–QuadIPFEPublicKey
- class pyfe4ai.core.formats.pairing.QuadFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of Quad.
Fields, in wire order:
f–n x mmatrix of decimal stringsk–2 m + 3 n + 4G2 elements
- class pyfe4ai.core.formats.pairing.QuadCiphertext(raw)[source]¶
Bases:
RecordCiphertext of Quad.
Fields, in wire order:
ct_x–nG1 elementsct_y–mG2 elementsct–2 m + 3 n + 4G1 elements
- class pyfe4ai.core.formats.pairing.SGPRecord(raw)[source]¶
Bases:
RecordParameter record of SGP (DSGPP18; the configuration only).
Fields, in wire order:
sec_param– intn– intbound– decimal stringpairing_group_param– the pairing group
- class pyfe4ai.core.formats.pairing.SGPParameters(raw)[source]¶
Bases:
RecordPublic parameters (the public key) of SGP.
Fields, in wire order:
n– intbound– decimal stringpairing_group_param– the pairing groupg1– G1g2– G2g1_s–nG1 elementsg2_t–nG2 elements
- class pyfe4ai.core.formats.pairing.SGPFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of SGP.
Fields, in wire order:
key– G2f–n x nmatrix of decimal strings
- class pyfe4ai.core.formats.pairing.SGPCiphertext(raw)[source]¶
Bases:
RecordCiphertext of SGP.
Fields, in wire order:
c0– G1a–n x 2G1 elementsb–n x 2G2 elements
- class pyfe4ai.core.formats.pairing.MIQFEParameters(raw)[source]¶
Bases:
RecordPublic parameters of the multi-input quadratic FE (AGT22).
Fields, in wire order:
pairing_group_param– the pairing groupg1– G1g2– G2n– int, the number of usersm– int, each user’s input lengthmddh_k– intlst_nid– the user idsbound_x– intbound_c– intsec_param– int
- class pyfe4ai.core.formats.pairing.MIQFECiphertext(raw)[source]¶
Bases:
RecordA master ciphertext
MstEncof the multi-input quadratic FE, and a user’s ciphertext (their combination, the same layout).Fields, in wire order:
ct–mrows of G1 elementssk–mrows of G2 elementsct2– G1 elementssk2– G2 elementsmg_ct– G1 elementsmg_sk– G2 elements
- class pyfe4ai.core.formats.pairing.MIQFEEncryptionKey(raw)[source]¶
Bases:
RecordEncryption key
EK_iof a user: master ciphertexts only.Fields, in wire order:
mct1–mMIQFECiphertextmct0–4 m + 2 k + 17MIQFECiphertext
- class pyfe4ai.core.formats.pairing.MIQFEFunctionalKey(raw)[source]¶
Bases:
RecordFunctional key of the multi-input quadratic FE.
Fields, in wire order:
c–nm x nmmatrix of decimal stringsmg_sk–nrows of G2 elementsmg_ct–nrows of G1 elementssigma–n x nmatrix of decimal strings
The serialized objects of the threshold schemes: key shares (whole, and the weight and label parts of the threshold MCFE over Ring-LWE), the pieces of the replicated sharings, and partial decryptions.
ThresholdKeyShare and PartialDecryption are the views the
shared threshold code (pyfe4ai.schemes.threshold) reads any scheme’s
key shares and partials through; the other classes are the layouts of each
scheme. A key share of the replicated sharings holds sharing and
pieces (and, seeded, seeds and layout) in place of the shared
values; one of the Shamir sharing holds the values (sk_y, z, …).
- class pyfe4ai.core.formats.threshold.KeyPiece(raw)[source]¶
Bases:
RecordA piece
r_Tof a replicated sharing, as a server holds it.Fields, in wire order:
set– the index setT(sorted server points)share– the piece: the shared material’s structure (sk_y,z, …)
- class pyfe4ai.core.formats.threshold.KeySeed(raw)[source]¶
Bases:
RecordThe seed of a piece of the seed-expanded replicated sharing.
Fields, in wire order:
set– the index setTseed– 32-byte hex seed
- pyfe4ai.core.formats.threshold.PIECE_FIELDS = ('pieces', 'seeds', 'layout')¶
The fields of a key share that hold the pieces of a replicated sharing.
Bases:
RecordAny threshold key share, as the shared server code reads it (the fields of every scheme’s key share that the checks and the sums of
pyfe4ai.schemes.thresholduse).Fields, in wire order:
sharing–replicatedorreplicated-seeded(Shamir key shares have none) (absent: ‘shamir’)pieces– replicated: the server’s pieces (KeyPiece)seeds– seeded: the seeds of the other pieces (KeySeed)layout– seeded: the layout of a piecesk_y– the shared key of the weights (LWE, Ring-LWE)z– the shared term of the key (LWE, Ring-LWE: of the label; DDH, FH)z_chunks– tMCFE-Ring-LWE: the shared terms of the chunk labelsd– DDH: the shared keyk– FH: the shared key in the exponentpart– tMCFE-Ring-LWE:weightsorlabel(whole key shares have none) (optional)share_set_id– tMCFE-Ring-LWE: the weight part’s sharingsharing_id– tMCFE-Ring-LWE: this sharing (32-char hex) (optional)label– the label (tMCFE-Ring-LWE)noise_key– hex key of the server’s flooding noisesid– the server id (str or int)lst_sid– the server idsweights_id– hex digest of the weightskey_id– hex id of the sharing (tMCFE FH)mac_keys–{client: hex key}of the ciphertext tagsnoise_version– int, the flooding derivation (absent: 1)noise_sampler– the flooding samplerflooding–uniformorgaussian(absent: ‘gaussian’)label_hash– label hash mode (absent: ‘shake256-wide’)pp_binding– hex digest of the public parameters it was issued for
The key share’s other fields (a new dict, in their order).
- Return type:
Field names in wire order (set for every subclass).
Bases:
RecordKey share of the threshold MIFE over LWE (
pyfe4ai.schemes.mife.lwe_threshold).Fields, in wire order:
sharing– replicated sharings only (absent: ‘shamir’)pieces– replicated:KeyPieceof{sk_y, z}seeds– seeded:KeySeedlayout– seeded: the piece layoutsk_y– Shamir:{client: decimal strings}noise_key– hex key of the flooding noisez– Shamir: decimal stringnoise_version– int (absent: 1)noise_sampler– the flooding samplersid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weightsmac_keys–{client: hex key}pp_binding– hex digest
Field names in wire order (set for every subclass).
Bases:
RecordKey share of the threshold MCFE over LWE (
pyfe4ai.schemes.mcfe.lwe_threshold).Fields, in wire order:
sharing– replicated sharings only (absent: ‘shamir’)pieces– replicated:KeyPieceof{sk_y}seeds– seeded:KeySeedlayout– seeded: the piece layoutsk_y– Shamir: decimal stringssid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weightsnoise_key– hex key of the flooding noisenoise_version– int (absent: 1)noise_sampler– the flooding samplerlabel_hash– label hash mode (absent: ‘shake256-wide’)pp_binding– hex digest
Field names in wire order (set for every subclass).
Bases:
RecordWhole key share of the threshold MCFE over Ring-LWE (
pyfe4ai.schemes.mcfe.ring_lwe_threshold,key_part="full"): shares ofsk_y,zandz_chunks(Shamir; binary polynomials under binary public parameters) or the pieces of a replicated sharing.Fields, in wire order:
sharing– replicated sharings only (absent: ‘shamir’)pieces– replicated:KeyPieceof{sk_y, z, z_chunks}seeds– seeded:KeySeedlayout– seeded: the piece layoutsk_y– Shamir:{client: polynomial}z– Shamir: polynomialz_chunks– Shamir: polynomialslabel– strnoise_key– hex key of the flooding noise (per server, weights and label)sharing_id– 32-char hex, this sharing (optional)sid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weightsmac_keys–{client: hex key}noise_version– int (absent: 1)noise_sampler– the flooding samplerflooding–uniformorgaussian(absent: ‘gaussian’)label_hash– label hash mode (absent: ‘shake256-wide’)pp_binding– hex digest
Field names in wire order (set for every subclass).
Bases:
RecordWeight part of a split key share of the threshold MCFE over Ring-LWE (
part = "weights"; once per weights and share set).Fields, in wire order:
sharing– replicated only (absent: ‘shamir’)pieces– replicated:KeyPieceof{sk_y}sk_y– Shamir:{client: polynomial}part–weightsshare_set_id– 32-char hex, this sharing ofsk_ysid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weightsmac_keys–{client: hex key}noise_version– int (absent: 1)noise_sampler– the flooding samplerflooding–uniformorgaussian(absent: ‘gaussian’)label_hash– label hash mode (absent: ‘shake256-wide’)pp_binding– hex digest
Field names in wire order (set for every subclass).
Bases:
RecordLabel part of a split key share of the threshold MCFE over Ring-LWE (
part = "label"; per label, completing the weight part of itsshare_set_id).Fields, in wire order:
sharing– replicated only (absent: ‘shamir’)pieces– replicated:KeyPieceof{z, z_chunks}z– Shamir: polynomial (absent withlabel_term=False)z_chunks– Shamir: polynomialslabel– strnoise_key– hex key of the flooding noisepart–labelshare_set_id– the weight part’s sharinglabel_hash– label hash mode (absent: ‘shake256-wide’)sharing_id– 32-char hex, this sharing of the label’s terms (optional)sid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weightsmac_keys–{client: hex key}noise_version– int (absent: 1)noise_sampler– the flooding samplerflooding–uniformorgaussian(absent: ‘gaussian’)pp_binding– hex digest
Field names in wire order (set for every subclass).
Bases:
RecordKey share of the threshold MIFE over DDH (
pyfe4ai.schemes.mife.ddh_threshold; Shamir).Fields, in wire order:
d–{client: decimal string}z– decimal stringsid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weights
Field names in wire order (set for every subclass).
Bases:
RecordKey share of the threshold MCFE over DDH (
pyfe4ai.schemes.mcfe.ddh_threshold; Shamir).Fields, in wire order:
d– two decimal stringssid– the server id (str or int)lst_sid– server idsweights_id– hex digest of the weights
Field names in wire order (set for every subclass).
Bases:
RecordKey share of the threshold FH-MCFE (
pyfe4ai.schemes.mcfe.fh_multi_ipe_pairing_threshold; shares in the exponent).Fields, in wire order:
k–{client: serialised G2 elements}z– serialised GT elementsid– the server id (str or int)lst_sid– server idskey_id– 32-char hex, this sharingmac_keys–{client: hex key}
Field names in wire order (set for every subclass).
- class pyfe4ai.core.formats.threshold.TaggedCiphertext(raw)[source]¶
Bases:
RecordAny ciphertext of the threshold schemes whose servers check client tags (tMIFE-LWE, tMCFE-Ring-LWE, tMCFE FH; the other fields are the scheme’s).
Fields, in wire order:
tags–{server: hex HMAC-SHA256}under the client-server keys
- class pyfe4ai.core.formats.threshold.PartialDecryption(raw)[source]¶
Bases:
RecordAny partial decryption, as the shared combiner code reads it.
Fields, in wire order:
w– the server’s key partc_y– the weighted ciphertextsu_d– tMCFE DDH: the label termk– tMCFE-Ring-LWE: int, the batch lengthct_digest– hex digest of the decrypted ciphertextskey_id– tMCFE FH: the key’s sharinglabel– the encoded labelsid– the server id (str or int)lst_sid_enrolled– the servers whose partials are combinedsharing_id– tMCFE-Ring-LWE: the key share’s sharing (optional)
- class pyfe4ai.core.formats.threshold.TMCFERingLWEPartial(raw)[source]¶
Bases:
RecordPartial decryption of the threshold MCFE over Ring-LWE:
wandc_yas decimal strings (ring_nvalues, JSON public parameters) or bytes (kwords, binary ones).Fields, in wire order:
w– values or bytesc_y– values or bytesk– int, the batch lengthct_digest– hex digestsid– the server id (str or int)lst_sid_enrolled– server idssharing_id– the key share’ssharing_id(or null) (optional)
- class pyfe4ai.core.formats.threshold.TMCFERingLWELayerPartials(raw)[source]¶
Bases:
RecordOne server’s partial decryptions of a packed ndarray layer (one per chunk).
Fields, in wire order:
shape– list of intsparts–TMCFERingLWEPartial
- class pyfe4ai.core.formats.threshold.TMIFELWEPartial(raw)[source]¶
Bases:
RecordPartial decryption of the threshold MIFE over LWE.
Fields, in wire order:
w– decimal stringc_y– decimal stringct_digest– hex digest of the canonical ciphertextssid– the server id (str or int)lst_sid_enrolled– server ids
- class pyfe4ai.core.formats.threshold.TMCFELWEPartial(raw)[source]¶
Bases:
RecordPartial decryption of the threshold MCFE over LWE.
Fields, in wire order:
w– decimal stringc_y– intlabel– the encoded labelsid– the server id (str or int)lst_sid_enrolled– server ids
- class pyfe4ai.core.formats.threshold.TMIFEDDHPartial(raw)[source]¶
Bases:
RecordPartial decryption of the threshold MIFE over DDH.
Fields, in wire order:
c_y– decimal stringw– decimal stringct_digest– hex digest of the requestsid– the server id (str or int)lst_sid_enrolled– server ids
- class pyfe4ai.core.formats.threshold.TMCFEDDHPartial(raw)[source]¶
Bases:
RecordPartial decryption of the threshold MCFE over DDH.
Fields, in wire order:
c_y– decimal stringu_d– decimal stringlabel– the encoded labelsid– the server id (str or int)lst_sid_enrolled– server ids
- class pyfe4ai.core.formats.threshold.TMCFEFHPartial(raw)[source]¶
Bases:
RecordPartial decryption of the threshold FH-MCFE.
Fields, in wire order:
w– serialised GT elementct_digest– hex digestkey_id– the key share’skey_idlabel– the encoded labelsid– the server id (str or int)lst_sid_enrolled– server ids
Server and Client Ids¶
Server and client ids.
A server id (sid: an entry of lst_sid, the server of a key share or a
partial decryption) or a client id (nid: an entry of lst_nid, the
client of a ciphertext or an encrypted gradient) is a str or an int
(not a bool): is_id(). A key generator refuses a lst_sid or
lst_nid of other values, or one that mixes str and int ids
(check_id_list()); partial decryptions and the wire records of the ML
adapter carry ids of these types only, and messages that list ids order them
with id_list().
Where an id enters after setup – the server or client named when keys are
issued, a crypto object’s own id, the enrolled servers of a partial
decryption, the servers of the ML adapter, the ids of partial decryptions and
encrypted gradients read back – a numpy integer scalar is read as the
int it equals (as_id(); list(rng.choice(lst_sid, t)) gives
such ids), and then the same rule and the same membership checks apply.
- pyfe4ai.core.ids.ID_LISTS = {'lst_nid': 'lst_nid must be a list of client ids, each a str or an int (convert numpy integers with int(), other ids with str())', 'lst_sid': 'lst_sid must be a list of server ids, each a str or an int (convert numpy integers with int(), other ids with str())'}¶
What a list of ids must be, by option name (the text of the
FEValidationErrorfor a list that is not one).
- pyfe4ai.core.ids.MIXED_IDS = {'lst_nid': 'lst_nid mixes str and int client ids (convert them all with str(), or all with int())', 'lst_sid': 'lst_sid mixes str and int server ids (convert them all with str(), or all with int())'}¶
The
FEValidationErrortext for a list that mixesstrandintids, by option name: JSON names1and"1"alike, and sorting such ids (canonical JSON digests, messages) fails.
- pyfe4ai.core.ids.DUPLICATE_IDS = {'lst_nid': 'lst_nid contains duplicate client ids', 'lst_sid': 'lst_sid contains duplicate server ids'}¶
The
FEValidationErrortext for a repeated id, by option name.
- pyfe4ai.core.ids.is_id(value)[source]¶
Whether value is a server or client id: a
str, or anintother than abool.- Return type:
- pyfe4ai.core.ids.as_id(value)[source]¶
value read as an id after setup: a numpy integer scalar (
numpy.integer;numpy.bool_is none) becomes theintit equals (operator.index), which it also hashes like; every other value is returned unchanged, foris_id()and the membership checks to judge (a float, abool,Nonestay what they are).
- pyfe4ai.core.ids.issued_id(value)[source]¶
value read as the id a key is issued for:
as_id()of it if that is an id, elseNone– which nolst_sidorlst_nidholds, so that the key generator answers as for an unknown server or client (None), also forTrueor1.0, which equal the id1.
- pyfe4ai.core.ids.id_list(ids)[source]¶
ids sorted for a message: by value, or by
reprwhere the values do not compare ([1, "a"]), so that listing ids never raises.- Return type:
- pyfe4ai.core.ids.check_id_list(ids, option)[source]¶
Raise unless ids (the value of the option option,
"lst_sid"or"lst_nid") is a list (or tuple) of distinct ids, allstror allint.The lists themselves are taken as given (numpy integers are refused here, not read as ints: the key generator keeps the list, and the public parameters and key shares carry it).
- Raises:
FEValidationError –
ID_LISTS[option]for another value (a string, a set, a dict, an iterator) or an entry that is not an id (bytes, a float,None, abool, a tuple, a numpy integer),MIXED_IDS[option]forstrandintids in one list,DUPLICATE_IDS[option]for a repeated id.- Parameters:
option (
str)- Return type:
Versions and Compatibility¶
Versions and compatibility: what every version marker means, what a missing marker means, and the checks that accept, refuse or regenerate an artifact.
The serialized objects of a scheme (public parameters, parameter records,
keys, key shares, ciphertexts, partial decryptions; their layouts are in
pyfe4ai.core.formats) carry markers of the derivation that made them.
Versions <= 0.3.0 wrote fewer markers, so for most of them an absent field has
a meaning – the derivation of those versions:
Marker |
Absent means |
Decided by |
|---|---|---|
|
|
|
key shares) |
( |
|
|
code 0 ( |
|
(ciphertexts, layers) |
|
|
|
|
|
pp) |
||
|
|
|
shares) |
||
|
none (Shamir only) |
|
|
1 (refused) |
|
|
|
|
|
none (combines only with partials without one) |
|
|
a whole key share |
|
key shares) |
||
|
refused |
|
(pickled state) |
||
record ids ( |
regenerated |
|
|
Shamir key shares with t < s (the sharing of versions <= 0.3.0) are
served only under the legacy_shamir policy of check_legacy_shamir().
The identifiers are those of earlier versions; nothing here changes a digest
or a record. The byte formats’ own version bytes (format 1 and 2 of the
Ring-LWE ciphertexts) are in pyfe4ai.core.formats.binary.
- pyfe4ai.core.versions.SIFE_LWE_RECORD = 'abdp15-lwe-seeded-a/v1'¶
Record id of SIFE LWE (ABDP15 with a seeded
A; record fieldconstruction).
- pyfe4ai.core.versions.MIFE_LWE_RECORD = 'acfgu18-abdp15-lwe-seeded-a/v2'¶
Record id of MIFE LWE (record field
construction).
- pyfe4ai.core.versions.SIFE_FULLYSEC_LWE_RECORD = 'als16-lwe/v5'¶
Record id of SIFE FullySec LWE (
K = 2 eta X Y + 1, encodingfloor(q / K) x,m = 4 n log2 q,B_tau ~ sqrt(m); record fieldconstruction).
- pyfe4ai.core.versions.MIFE_FULLYSEC_LWE_RECORD = 'acfgu18-als16-lwe/v4'¶
Record id of MIFE FullySec LWE (
m = 4 n log2 q,B_tau ~ sqrt(m); record fieldconstruction).
- pyfe4ai.core.versions.SIFE_RING_LWE_RECORD = 'bmms21-sec4.2/v3'¶
Record id of SIFE Ring-LWE (
p = 2 l X Y + 2, Sec. 4.2 widths, seededa; record fieldparam_version).
- pyfe4ai.core.versions.SIFE_FULLYSEC_RING_LWE_RECORD = 'bmms21-sec5/v2'¶
Record id of SIFE FullySec Ring-LWE, element-wise layout (
aexpanded from a stored seed;param_version).
- pyfe4ai.core.versions.SIFE_FULLYSEC_RING_LWE_PACKED_RECORD = 'bmms21-sec5-packed/v2'¶
Record id of SIFE FullySec Ring-LWE, packed layout (leveraging over the span of the differences; v2:
eta = 1with the basis[1];param_version).
- pyfe4ai.core.versions.RING_LWE_RECORD = 'acfgu18-bmms21/v5'¶
Record id of the MIFE / MCFE / dMCFE / tMCFE Ring-LWE family (sized for
n eta,p = 2T + 2, Sec. 4.2 widths for3X, seededa; record fieldconstruction).
- pyfe4ai.core.versions.PAILLIER_RECORD = 'modulus-only/v1+g-seed'¶
Record format of the SIFE and MIFE Paillier records (versions <= 0.2.0 also stored
pandq; record fieldparam_format).
- pyfe4ai.core.versions.MCFE_PAILLIER_RECORD = 'abmpsw20-dcr/v2'¶
Record id of MCFE Paillier (v1 records stored
pandq; record fieldconstruction).
- pyfe4ai.core.versions.MCFE_DAMGARD_RECORD = 'abmpsw20-mddh/v1'¶
Record id of MCFE Damgard (MDDH; record field
construction).
- pyfe4ai.core.versions.TMCFE_DDH_RECORD = 'cdgpp18-shamir/v1'¶
Record id of the threshold MCFE over DDH (record field
construction).
- pyfe4ai.core.versions.DMCFE_DDH_RECORD = 'abmpsw20-fig14-cdgpp18-dcr-carry-mask/v2'¶
Record id of the decentralised MCFE over DDH (record field
construction).
- pyfe4ai.core.versions.DMCFE_LWE_RECORD = 'abmpsw20-fig14-lwe-dcr/v2'¶
Record id of the decentralised MCFE over LWE (record field
construction).
- pyfe4ai.core.versions.DMCFE_PAILLIER_RECORD = 'abmpsw20-fig14-dcr-dcr/v1'¶
Record id of the decentralised MCFE over DCR (record field
construction).
- pyfe4ai.core.versions.MIFE_DDH_CONSTRUCTION = 'acfgu18-abdp15/v2'¶
Public-parameter
constructionof MIFE DDH (published, not checked).
- pyfe4ai.core.versions.MIFE_DDH_RISTRETTO255_CONSTRUCTION = 'acfgu18-abdp15-ristretto255/v1'¶
Public-parameter
constructionof MIFE DDH over ristretto255 (published, not checked).
- pyfe4ai.core.versions.RECORD_ABSENT = {'ndarray_layout': 'elementwise', 'ring_modulus': 'prime'}¶
The meaning of an absent field of a parameter record (a record of an earlier version) – the prime modulus of the Ring-LWE family, the element-wise layout of SIFE FullySec Ring-LWE.
- pyfe4ai.core.versions.record_matches(param, expected)[source]¶
Whether the parameter record param has the expected value of every field (in order, stopping at the first difference; an absent field is
RECORD_ABSENT’s value, elseNone). A record that does not match is regenerated by the parameter cache (ParameterCacheMixin).
- pyfe4ai.core.versions.caches_record(key_generator)[source]¶
Whether a key generator keeps its parameter record in the cache: not one whose parameters include a DCR modulus under the
standardprofile (no check can tell whether someone knows its factors, so such parameters are generated afresh, never loaded or stored).- Return type:
- pyfe4ai.core.versions.LEGACY_SHARING = 'shamir'¶
The meaning of an absent
sharing(pp and key shares) – the only sharing of versions <= 0.3.0.
- pyfe4ai.core.versions.TMIFE_LWE_CONSTRUCTION = 'acfgu18-abdp15-shamir-smudging-seeded-a/v4'¶
The construction id of tMIFE-LWE (
pyfe4ai.schemes.mife.lwe_threshold) with the Shamir sharing.
- pyfe4ai.core.versions.TMIFE_LWE_CONSTRUCTION_KL = 'acfgu18-abdp15-shamir-smudging-kl/v2'¶
The construction id of tMIFE-LWE with the Shamir sharing and the KL accounting of the flooding.
- pyfe4ai.core.versions.TMIFE_LWE_CONSTRUCTION_REPLICATED = 'acfgu18-abdp15-replicated-smudging-seeded-a/v1'¶
The construction id of tMIFE-LWE with the replicated sharing.
- pyfe4ai.core.versions.TMIFE_LWE_CONSTRUCTION_REPLICATED_SEEDED = 'acfgu18-abdp15-replicated-seeded-smudging-seeded-a/v1'¶
The construction id of tMIFE-LWE with the seed-expanded replicated sharing.
- pyfe4ai.core.versions.TMIFE_LWE_CONSTRUCTIONS = {'acfgu18-abdp15-replicated-seeded-smudging-seeded-a/v1': 'replicated-seeded', 'acfgu18-abdp15-replicated-smudging-seeded-a/v1': 'replicated', 'acfgu18-abdp15-shamir-smudging-kl/v2': 'shamir', 'acfgu18-abdp15-shamir-smudging-seeded-a/v4': 'shamir'}¶
The sharing of each tMIFE-LWE construction id.
- pyfe4ai.core.versions.TMCFE_LWE_CONSTRUCTION = 'abmpsw20-shamir-flooding/v1'¶
The construction id of tMCFE-LWE (
pyfe4ai.schemes.mcfe.lwe_threshold) with the Shamir sharing.
- pyfe4ai.core.versions.TMCFE_LWE_CONSTRUCTION_REPLICATED = 'abmpsw20-replicated-flooding/v1'¶
The construction id of tMCFE-LWE with the replicated sharing.
- pyfe4ai.core.versions.TMCFE_LWE_CONSTRUCTION_REPLICATED_SEEDED = 'abmpsw20-replicated-seeded-flooding/v1'¶
The construction id of tMCFE-LWE with the seed-expanded replicated sharing.
- pyfe4ai.core.versions.TMCFE_LWE_CONSTRUCTIONS = {'abmpsw20-replicated-flooding/v1': 'replicated', 'abmpsw20-replicated-seeded-flooding/v1': 'replicated-seeded', 'abmpsw20-shamir-flooding/v1': 'shamir'}¶
The sharing of each tMCFE-LWE construction id.
- pyfe4ai.core.versions.TMCFE_RING_LWE_CONSTRUCTION_IDS = {('replicated', 'gaussian'): 'bmms21-ibmcfe-replicated-smudging/v1', ('replicated', 'uniform'): 'bmms21-ibmcfe-replicated-smudging-uniform/v1', ('replicated-seeded', 'gaussian'): 'bmms21-ibmcfe-replicated-seeded-smudging/v1', ('replicated-seeded', 'uniform'): 'bmms21-ibmcfe-replicated-seeded-smudging-uniform/v1', ('shamir', 'gaussian'): 'bmms21-ibmcfe-shamir-smudging/v2', ('shamir', 'uniform'): 'bmms21-ibmcfe-shamir-smudging-uniform/v1'}¶
The parameter record (and public
threshold_construction) of a sharing and a flooding of tMCFE-Ring-LWE (pyfe4ai.schemes.mcfe.ring_lwe_threshold) under the per-sample accounting ("kl":TMCFE_RING_LWE_CONSTRUCTION_KL).
- pyfe4ai.core.versions.TMCFE_RING_LWE_CONSTRUCTION_KL = 'bmms21-ibmcfe-shamir-smudging-kl/v2'¶
The construction id of tMCFE-Ring-LWE with the Shamir sharing, Gaussian flooding and KL accounting.
- pyfe4ai.core.versions.TMCFE_RING_LWE_CONSTRUCTIONS = {'bmms21-ibmcfe-replicated-seeded-smudging-uniform/v1': 'replicated-seeded', 'bmms21-ibmcfe-replicated-seeded-smudging/v1': 'replicated-seeded', 'bmms21-ibmcfe-replicated-smudging-uniform/v1': 'replicated', 'bmms21-ibmcfe-replicated-smudging/v1': 'replicated', 'bmms21-ibmcfe-shamir-smudging-kl/v2': 'shamir', 'bmms21-ibmcfe-shamir-smudging-uniform/v1': 'shamir', 'bmms21-ibmcfe-shamir-smudging/v2': 'shamir'}¶
The sharing of each tMCFE-Ring-LWE construction id.
- pyfe4ai.core.versions.tmcfe_ring_lwe_construction_id(sharing, flooding, accounting)[source]¶
The tMCFE-Ring-LWE construction id of a sharing, a flooding and a flooding accounting (
Nonefor a combination the key generator does not make).
- pyfe4ai.core.versions.check_served_sharing(pp, dk, constructions)[source]¶
Raise unless key share dk is of the sharing that pp describes.
pp["sharing"]must match the key share (both default to"shamir", the only sharing of versions <= 0.3.0). Public parameters of this version recordthreshold_construction; it must be one of constructions ({construction id: sharing}) and name that sharing, so that artifacts of another construction (a later version, say) are refused rather than misread. Only Shamir public parameters may lack it (those of versions <= 0.3.0); every version with the replicated sharing records it, so replicated public parameters without it are refused.
- pyfe4ai.core.versions.check_tmife_lwe_construction(pp, kl)[source]¶
Raise unless tMIFE-LWE public parameters that record a construction id record that of their flooding accounting (kl:
"kl").- Raises:
FESchemeError – For the id of the other accounting.
- Parameters:
- Return type:
- pyfe4ai.core.versions.check_tmcfe_ring_lwe_construction(pp, sharing, flooding, accounting)[source]¶
Raise unless tMCFE-Ring-LWE public parameters that record a construction id record that of the key share’s sharing, their flooding and accounting (
tmcfe_ring_lwe_construction_id()).
- pyfe4ai.core.versions.LEGACY_SHAMIR_POLICIES = ('refuse', 'warn')¶
What a server does with a Shamir key share whose
t < s(crypto config entrylegacy_shamir):"refuse"(default) or"warn"(serve it with anFESecurityWarning). Key shares of versions <= 0.3.0 are refused before this applies (their flooding derivation, seecheck_flooding_version()), so"warn"serves the explicit Shamirt < sshares of this version undertoy. There is deliberately no environment variable: the opt-out is per server object.
- pyfe4ai.core.versions.legacy_shamir_policy(config)[source]¶
The
legacy_shamirentry of a server’s crypto config (default"refuse").
- pyfe4ai.core.versions.check_legacy_shamir(sid, threshold, s, legacy_shamir, profile)[source]¶
Serve server sid’s Shamir key share with
t < sonly under thelegacy_shamir = "warn"policy and not under thestandardprofile of the public parameters (profile;Nonefor those of versions <= 0.3.0), with a warning;t = sis served.- Raises:
FESchemeError – For such a key share that is not to be served.
- Warns:
FESecurityWarning – When it is served; attributed to the application’s call (the first frame outside pyfe4ai,
warn_at_caller()).- Parameters:
- Return type:
- pyfe4ai.core.versions.MIXED_SHARINGS = "partials come from different sharings of the label's key; fetch the label parts again from the key generator for all servers"¶
The message of
MixedSharingsError.
- exception pyfe4ai.core.versions.MixedSharingsError[source]¶
Bases:
FESchemeErrorPartial decryptions of different sharings of one key were combined.
Every sharing a key generator issues (whole key shares, or the label parts of one label) has a random
sharing_id, which the servers’ partial decryptions carry. Shares of two sharings of the same key do not reconstruct it: combined, their partials would decode to a wrong value inside the decoding bound rather than fail. This happens when the label parts of one round are fetched on both sides of their eviction (LABEL_PARTS_KEPT); fetch them again for all servers. The check needs the ids: keep thesharing_idwith every stored or transmitted key share and partial decryption (partials without one combine only with each other).
The
sharing_idof a key share (Nonefor key shares of earlier versions, which have none), which its partial decryptions carry.- Raises:
FEKeyError – For a
sharing_idthat is not a string.- Parameters:
dk (
dict)- Return type:
- pyfe4ai.core.versions.check_partials_sharing(partials)[source]¶
Raise unless the partial decryptions are of one sharing: shares of two sharings of one key do not reconstruct it (their partials would decode to a wrong value). Partials without a
sharing_idcombine only with each other.- Raises:
FESchemeError – For a
sharing_idthat is not a string.MixedSharingsError – For partials of different sharings.
- Parameters:
partials (
list)- Return type:
The
partof a tMCFE-Ring-LWE key share:"weights","label", orNonefor a whole key share (versions <= 0.3.0 issued only those;key_part="full"still does).
- pyfe4ai.core.versions.FLOODING_NOISE_VERSION = 2¶
Version of the flooding-noise derivation in the decryption keys of the threshold schemes (tMIFE-LWE, tMCFE-LWE, tMCFE-Ring-LWE;
noise_version): 2 sinceBIGINT_GUARD_BITSgrew (keys without the field are version 1).
- pyfe4ai.core.versions.check_flooding_version(dk)[source]¶
Refuse a threshold decryption key of another flooding derivation: it may have answered a request with the noise of the earlier derivation, and a second noise for the same request would let the answers be averaged.
- Raises:
FEKeyError – For a key of another version (issue new keys).
- Return type:
- pyfe4ai.core.versions.LEGACY_FLOODING = 'gaussian'¶
The flooding of versions <= 0.3.0 and of public parameters (and key shares) without
flooding.
- pyfe4ai.core.versions.pp_flooding(pp)[source]¶
The
floodingof tMCFE-Ring-LWE public parameters (absent:LEGACY_FLOODING).
- pyfe4ai.core.versions.check_key_flooding(pp_value, dk, floodings)[source]¶
Raise unless the public parameters’ flooding pp_value is one of floodings and key share dk was issued for it (absent in either:
LEGACY_FLOODING).- Raises:
FEValidationError – For an unknown flooding of the public parameters.
FEKeyError – For a key share of another flooding.
- Parameters:
- Return type:
- pyfe4ai.core.versions.label_hash_mode(value)[source]¶
value if it is one of
LABEL_HASHES.- Raises:
FEValidationError – Otherwise.
- Return type:
- pyfe4ai.core.versions.pp_label_hash(pp)[source]¶
The
label_hashof public parameters (absent:"shake256-wide", the hash of versions <= 0.3.0).- Raises:
FEValidationError – If it is not one of
LABEL_HASHES.- Parameters:
pp (
dict)- Return type:
- pyfe4ai.core.versions.key_label_hash(key)[source]¶
The
label_hasha key, key share or encryption key was issued for (absent:"shake256-wide").
- pyfe4ai.core.versions.check_key_label_hash(key, mode, subject='the key was')[source]¶
Raise unless key (a functional key or key share) was derived for the public parameters’ label hash mode (
key_label_hash()).- Raises:
FESchemeError –
"<subject> derived with another label hash than the public parameters".- Parameters:
- Return type:
- pyfe4ai.core.versions.check_encryption_key_label_hash(sk, mode)[source]¶
mode if the encryption key sk was issued for that label hash (keys without
label_hash:"shake256-wide").- Raises:
FEKeyError – If they differ (e.g. public parameters of another version than the key): the ciphertexts would decrypt to wrong values.
- Parameters:
- Return type:
- pyfe4ai.core.versions.label_hash_code(mode)[source]¶
The code a ciphertext of label hash mode carries (
LABEL_HASH_CODES),Nonefor"shake256-wide": its ciphertexts carry none, as in versions <= 0.3.0.
- pyfe4ai.core.versions.ciphertext_label_hash(ct)[source]¶
The label hash a ciphertext or ndarray layer dict was produced with (no
label_hashfield:"shake256-wide"), orNonefor an unknown code.
- pyfe4ai.core.versions.check_ciphertext_label_hashes(cts, mode, who='a client')[source]¶
Raise unless every ciphertext dict of cts was produced with mode.
- Raises:
FESchemeError – For a ciphertext of another (or an unknown) label hash.
- Parameters:
- Return type:
- pyfe4ai.core.versions.check_lwe_ciphertext_label_hash(ct, nid, mode, absent)[source]¶
Raise unless a dense MCFE-LWE ciphertext carries the code of mode (absent: the code of a ciphertext without one – 0, the hash of versions <= 0.3.0, for a single ciphertext; its layer’s for an element of an ndarray layer, whose first element carries the code).
- Raises:
FESchemeError – For a ciphertext of another label hash.
- Parameters:
- Return type:
- pyfe4ai.core.versions.check_lwe_layer_label_hash(first, nid, mode)[source]¶
Raise unless the first element first of a dense MCFE-LWE ndarray layer carries the code of mode (none:
"shake256-wide").- Raises:
FESchemeError – For a layer of another (or an unknown) label hash.
- Parameters:
mode (
str)- Return type:
- pyfe4ai.core.versions.CT_FORMATS = ('json', 'binary')¶
The ciphertext formats of the Ring-LWE schemes,
"json"(decimal strings) and"binary". For the MIFE / MCFE crypto objects (configct_format, default"json")"binary"is format 1 (encode_binary_ciphertext()); for the threshold MCFE over Ring-LWE it is a public parameter (key generator configct_format, default"binary";pp_ct_format()): format 2 (encode_threshold_ciphertext()), tags over its digests, binary partial decryptions."json"is the only format of versions <= 0.3.0 and that of threshold public parameters withoutct_format.
- pyfe4ai.core.versions.pp_ct_format(pp)[source]¶
The ciphertext format of threshold public parameters (absent:
"json").- Raises:
FEValidationError – For another value.
- Parameters:
pp (
dict)- Return type:
- pyfe4ai.core.versions.TMCFE_RING_LWE_STATE_VERSION = 'pyfe4ai/tmcfe-ring-lwe/state/2026-10-3'¶
The version of the pickled state of the tMCFE-Ring-LWE objects (a state pickled by another version of pyfe4ai, with other attributes or other derivations, is refused when loaded).
Configuration¶
The config classes and option rules (pyfe4ai.core.config) are
documented on Configuration, every scheme’s options on
Configuration options.
Offline Phases and One-Time Precomputations¶
One-time use of a precomputation (the offline phase of an encryption).
A precomputation holds the secret randomness or label masks of future
ciphertexts; using it twice encrypts two plaintexts with the same randomness
(or twice under one label), and their difference follows without any key.
OneTimePrecomputation makes the use atomic and keeps it in one
process:
_claimchecks and setsusedunder a per-object lock and moves the secret parts out of the object, so of two threads exactly one gets them;a precomputation records the process that made it and refuses to be used in another one; after
os.fork()the child’s copies are also marked used and dropped (pyfe4ai.core.forksafe.track());copy.copy,copy.deepcopyand pickling raiseTypeError: a copy would be a second, unused handle on the same randomness. Code that clones the object deliberately (copying its attributes) is not prevented; the object is a handle on a secret, not a capability that cannot be forged.
The schemes validate their inputs before they claim the precomputation, so refused inputs do not consume it.
Offline / online encryption of the element-wise schemes with fresh
randomness per ciphertext (OfflineRandomMixin): SIFE- and
MIFE-Paillier (ALS16 over DCR) encrypt as (g^r, (1 + N)^x pk^r) and
MIFE-DDH as (g^r, g^{x + u} h^r) with a fresh r per ciphertext:
everything but the plaintext term depends on r and the key only, and
costs full-size exponentiations. OfflineRandomMixin.precompute() draws
r for every element of given layer shapes – in the order
encrypt_lst_ndarray draws them – and computes those powers;
encrypt_lst_ndarray(..., precomputed=...) then only multiplies in the
plaintext term. With the same random source the ciphertexts are those of the
plain call. The precomputation holds the secret randomness of future
ciphertexts: keep it like a key. It is one-time
(OneTimePrecomputation): the online phase validates its input, then
claims the precomputation atomically; copy.copy, copy.deepcopy,
pickling and use in another process are refused.
A scheme provides _random_part() (draws r; returns what the
ciphertext needs of it) and _encrypt_with(lst_pt, part) (the ciphertext
of encrypt for that part, with its checks), and names in
_online_bound the public parameter that bounds the plaintexts, if
_encrypt_with checks one (checked before the precomputation is used).
- class pyfe4ai.core.one_time.OneTimePrecomputation[source]¶
Bases:
objectBase of the offline phases’ results: secret, one-time, one process.
Subclasses list in
_secretthe attributes that hold the secret parts (dropped by_claimand in a forked child).
- pyfe4ai.core.one_time.check_online_bound(scheme, layers)[source]¶
The plaintext bound
pp[scheme._online_bound]of the online phase, checked on all layers before the precomputation is claimed.
- class pyfe4ai.core.one_time.RandomPrecomputation(owner, shapes, parts)[source]¶
Bases:
OneTimePrecomputationThe randomness-dependent parts of future ciphertexts. Secret, one-time.
- class pyfe4ai.core.one_time.OfflineRandomMixin[source]¶
Bases:
objectprecompute / precomputed= for the element-wise ndarray helpers.
Offline / online phases of the element-wise MCFE schemes over Z_p^* and Z_{N^2}^*.
In MCFE-DDH (CDGPP18), MCFE-Damgard and MCFE-Paillier (ABMPSW20 Fig. 3) a
ciphertext of x under label l is X(x) M(l) mod P: X(x) is g^x or
(1 + N)^x and the label mask M(l) a product of powers of the label’s
hashes with the client’s secret, which does not depend on x. Decryption
divides prod_i c_i^{y_i} by a key term of the label and the functional
key. Both label terms are the expensive part (exponents of 256 to 3072 bits)
and are known before the round, so:
OfflineMCFEMixin.precompute()computes a client’s masks for every element label of given layer shapes;encrypt_lst_ndarray(..., precomputed=...)then only computesX(x)and one product per element. The ciphertexts are those of the plain call (the encryption is deterministic). Secret and one-time, as the masks of the Ring-LWE MCFE (seepyfe4ai.core.one_time: claimed atomically after the input is validated;copy.copy,copy.deepcopy, pickling and use in another process are refused).OfflineMCFEMixin.prepare_key()computes the key terms of every element label for a functional key;decrypt_lst_ndarray_ctwith that key then only multiplies the ciphertexts and solves the discrete log.
A scheme provides _label_mask(label) (one mask per slot),
_encrypt_masked(lst_pt, masks), _key_term(dk, label) and
decrypt(..., term=...) with the checks of its plain methods, and names
in _online_bound the public parameter that bounds the plaintexts, if
_encrypt_masked checks one.
- class pyfe4ai.schemes.mcfe.offline.LabelPrecomputation(owner, label, shapes, masks)[source]¶
Bases:
OneTimePrecomputationA client’s label masks for one label and fixed layer shapes. Secret, one-time.
- class pyfe4ai.schemes.mcfe.offline.PreparedKeyTerms(label, shapes, terms)[source]¶
Bases:
objectThe key terms of every element label of a functional key (not secret beyond the key).
Fork Safety¶
What a forked child renews; the process-wide state and what threads,
copies, pickles and fork do to it are on Threads, Processes and Copies.
What a forked child process renews: the one fork handler of the library.
os.fork() copies the whole memory of the process but only the thread that
called it. A lock that another thread held at the fork stays held for ever
in the child, and per-process random state (buffered OS random bytes, the
secret parts of one-time precomputations) would be used by both processes.
This module registers the library’s only os.register_at_fork handler
(after_in_child); in the child it runs, in the order they were
registered:
renew_lock()– replace a process-wide lock (a module attribute) with a new one;call_in_child()– call a function (e.g. drop the buffered OS random bytes ofpyfe4ai.primitives.sampling);
and then track() – call _after_fork_in_child() of every tracked
object still alive (e.g. mark the one-time precomputations used and drop
their secret parts, pyfe4ai.core.one_time; give a
PartialDecryptionBudget or a
FESchemeWrapper a new lock).
Nothing runs in the parent, nor before the fork. A handler that raises is
reported on stderr as an os.register_at_fork hook’s exception is
(Exception ignored in: ... and the traceback), and the other handlers
still run. The registrations are made at import of the modules that own the
state, so the child renews what the parent had imported. The process-wide
state of the library and what a fork, a copy or a pickle does to it are
listed on the “Threads, processes and copies” page of the documentation.
- pyfe4ai.core.forksafe.renew_lock(owner, name, factory=<built-in function allocate_lock>)[source]¶
In a forked child, replace
owner.<name>(a module’s process-wide lock) withfactory(): the parent’s may be held by another thread, which the child does not have.The code using the lock must read
owner.<name>at every use (with _LOCK:in the owning module does), not keep a reference to it.
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.core.exceptions.FEError[source]¶
Bases:
ExceptionBase exception for all PyFE4AI errors.
- exception pyfe4ai.core.exceptions.FEConfigError[source]¶
Bases:
FEErrorConfiguration or parameter file error (missing, invalid, corrupt).
- exception pyfe4ai.core.exceptions.FEKeyError[source]¶
Bases:
FEErrorMissing or invalid cryptographic keys / credentials.
- exception pyfe4ai.core.exceptions.FEValidationError[source]¶
Bases:
FEError,ValueErrorInput validation failure (bound exceeded, shape mismatch, etc.).
- exception pyfe4ai.core.exceptions.FESchemeError[source]¶
Bases:
FEError,RuntimeErrorInternal scheme logic error (unexpected state, unsupported operation).
- exception pyfe4ai.core.exceptions.FESecurityWarning[source]¶
Bases:
UserWarningA scheme with a known security defect is being used.
See
pyfe4ai.core.statusand the README Scheme Status table. LikeFEWarning, it is attributed to the application’s call (the first caller outside pyfe4ai,warn_at_caller()).
- exception pyfe4ai.core.exceptions.FEWarning[source]¶
Bases:
UserWarningA condition an application should see that does not stop the call.
For example a cached parameter record that no longer matches its configuration and is regenerated (new parameters and seeds), a request answered with
None(an unknown id, a decryption out of range) or a slower fallback. The library also logs them (logging.getLogger("pyfe4ai")has only aNullHandler, so without a logging configuration this warning is what an application sees). Not a subclass ofFESecurityWarning: filtering one leaves the other.It is attributed to the application’s call (the first caller outside pyfe4ai, see
warn_at_caller()), so Python’s default filter shows it once per call site of the application, not once per library line. Its text holds no caller-supplied values (an unknown id is in the log record only).
- pyfe4ai.core.exceptions.warn_at_caller(message, category=<class 'pyfe4ai.core.exceptions.FEWarning'>)[source]¶
Issue message as a category warning attributed to the first frame outside the pyfe4ai package – the application’s call, however deep the library’s own calls are – or, if every frame is inside it, to the library function that issues it. Used by the library for
FEWarning.
Constants¶
Scheme-type constants and default parameter values used across PyFE4AI.
- class pyfe4ai.core.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_FULLYSEC_RING_LWE = 'SIFE_FULLYSEC_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_QUADRATIC_MIQFE = 'QUADRATIC_MIQFE'¶
- 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¶
Input Validation¶
Input validation shared by the schemes.
- pyfe4ai._validation.int_vector(values, name, length=None, bound=None)[source]¶
Return values as a list of Python ints, or raise
FEValidationError.Integer types (
int,numpy.integer,gmpy2.mpz) and integral floats are accepted; booleans and non-integral numbers are rejected instead of being truncated silently.
- pyfe4ai._validation.strict_int(value, name='input')[source]¶
value as an int; non-integral values raise (see
int_vector()).
- pyfe4ai._validation.scale_to_int(values, precision)[source]¶
Return
round(values * 10^precision)as anint64array.The ndarray helpers encode real-valued plaintexts with this: it rounds to the nearest integer (ties to even) instead of truncating toward zero, multiplies integer arrays exactly, and refuses NaN, infinities and values whose scaled magnitude is not exactly representable.
- Raises:
FEValidationError – For non-numeric, non-finite or too large values.
- Parameters:
precision (
int)- Return type: