Upgrading from 0.3.0¶
Version 0.4.0 reorganises the package: modules moved, scheme classes are
renamed after their scheme ids, the top-level package exports different
names, and schemes are built with pyfe4ai.create. Some defaults and serialized formats
changed too, and the threshold LWE layers need new keys. This page lists
what code written for 0.3.0 has to change; the
changelog
has every change.
Before you upgrade¶
Threshold LWE layers (
mife/lwe_threshold,mcfe/ring_lwe_threshold,mcfe/lwe_threshold): 0.4.0 refuses every key share issued by 0.3.0. Witht < severy partial decryption under 0.3.0 key shares leaks part of the decryption noise (see the README’s Known Issues), so finish with 0.3.0 only the rounds that must finish under the old keys; then re-key with 0.4.0 (Re-keying), whose fix changes how the key is shared.Pickles do not carry across versions: objects pickled by 0.3.0 that refer to a moved module or a renamed class do not load. Keep keys, public parameters and ciphertexts in their JSON form, and build the objects again.
The parameter cache moved from
./config/to the per-user cache directory (Environment variables and the parameter cache); move./config/authoritythere or setPYFE4AI_CACHE_DIR=./configto keep the 0.3.0 records (some are regenerated anyway, see Formats and defaults).
Imports and names¶
The top-level package no longer exports scheme classes. Build a scheme from its id, or import its classes, under their new names, from the family package:
# 0.3.0
from pyfe4ai import SIFE, SIFEKeyGenerator
kg = SIFEKeyGenerator({"sec_param": 128, "eta": 3})
# 0.4.0
import pyfe4ai
kg, SIFEDDH = pyfe4ai.create("sife/ddh", {"sec_param": 128, "eta": 3})
# or: from pyfe4ai.schemes.sife import SIFEDDH, SIFEDDHKeyGenerator
pyfe4ai exports create and CreatedScheme, the registry queries
list_schemes, get_scheme, CAPABILITIES, get_scheme_status
and SchemeStatus, every exception and warning (FEError,
FEConfigError, FEKeyError, FEValidationError, FESchemeError,
MixedSharingsError, FESecurityWarning, FEWarning) and
backend_info. import pyfe4ai no longer imports the scheme modules.
Renamed classes¶
Each class is named after its scheme id: Threshold or Decentralized,
then the family, then the variant in CamelCase; the key generator adds
KeyGenerator (SIFEDDH, SIFEDDHKeyGenerator). No alias remains at
an old name. Renamed since 0.3.0 (each with its ...KeyGenerator):
Scheme |
0.3.0 |
0.4.0 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The other classes keep their names (SIFELWE, MCFERingLWE,
ThresholdMCFERingLWE, DecentralizedMCFEPaillier, QuadraticSGP,
…). pyfe4ai.list_schemes
and the table on Choosing a scheme give every scheme’s classes.
Moved modules¶
No module remains at its 0.3.0 path:
0.3.0 |
0.4.0 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removed: configure logging in the application (see Warnings and logging below) |
Configuration types¶
The TypedDict classes of pyfe4ai.schemes.config_types are replaced
by the config classes of pyfe4ai.core.config, one per scheme. They
are dict subclasses, so dict configs keep working, and the names that
remain build configs as before (DDHConfig(sec_param=128, eta=3)).
Renamed: MultiInputQuadraticConfig → QuadraticMIQFEConfig,
PairingMultiIPEConfig → MIFEFHMultiIPEPairingConfig,
PartFHIPEConfig → SIFEPartFHIPEPairingConfig,
ThresholdDDHConfig → ThresholdConfig (and
ThresholdMIFEDDHConfig, ThresholdMCFEDDHConfig),
ThresholdLWEConfig → ThresholdSharingConfig (and
ThresholdMIFELWEConfig), ThresholdPairingMultiIPEConfig →
ThresholdMCFEFHMultiIPEPairingConfig; FEBaseConfig →
SchemeConfig. Configuration options lists every scheme’s options.
Behaviour changes¶
- Partial decryptions that disagree raise
combine_decryptof every threshold scheme raisesFESchemeError(“partial decryptions disagree on the ciphertexts they decrypted”) when the partial decryptions of one enrolled set were computed for different ciphertexts; 0.3.0 returnedNone. Code that tested forNoneto detect a faulty server catchesFESchemeError.Noneremains the answer to a value out of range.- Server and client ids
lst_sidandlst_nidholdstrorintids, one type per list; key generators refuse other values (bytes, floats,None,bool, tuples, numpy integers) and mixed lists withFEValidationError. Convert numpy integers withint()and other ids withstr()before building the key generator. After setup a numpy integer is read as theintit equals wherever an id is given, and values such as1.0orTrueare no ids (0.3.0 issued client 1’s key for them in most MIFE and MCFE schemes). Integer client ids now work in the DDH and pairing schemes, and integer server ids in tagged threshold ciphertexts after a JSON round trip. See Configuration options.- Stricter inputs
Ring-LWE key rows of shape
(ring_n, 1)and three-dimensional key containers are refused (FEKeyError;numpy.raveleach row). Threshold DDH servers accept key-share values only as the decimal strings the key generators write.EncryptedGradient.from_dictandEncryptedFeatures.from_dictcheck the layout and the field types of whatto_dictwrites (ValueErrorotherwise); packed Ring-LWE gradients now serialise (0.3.0 raisedKeyError). The ML adapter refuses a gradient filed under another client than the one it names.- Warnings and logging
The library no longer configures logging or writes log files (
./logs); thepyfe4ailogger has aNullHandler. What an application should see is also issued asFEWarning: a regenerated parameter record, a decryption out of range, a key requested for an unknown server (for an unknown client only in the DDH schemes; the others returnNonewithout a warning), a slower fallback, and, once per process, a missing Rust extension. EveryFEWarningandFESecurityWarningis attributed to the application’s call (the first frame outside pyfe4ai), so Python’s default filter shows it once per call site, and a filter on a module matches the application’s module, notpyfe4ai.*; filters by category (warnings.filterwarnings("ignore", category=FEWarning)) work as before.- Pairing groups
The pairing-based schemes default to BLS12-381 from the Rust extension, under both profiles (0.3.0: MNT224 under
toy, BN254 understandard). Keys, public parameters and ciphertexts of 0.3.0 cannot be read on it: passpairing_group_param="MNT224", with charm-crypto installed, to keep using them.- The
standardprofile refuses more mife/lwe_threshold, an explicitsharing="shamir"witht < s,gaussian_sampler="rounded"for the schemes that sample exactly by default, and ABDP15 dimensions below the new rule. Both profiles refusestat_paramabove 256 and thresholds that are not integers. Theddhkey generators refuse agroupother than"modp"(the elliptic-curve DDH is theddh_ristretto255variant).
Formats and defaults¶
Schemes |
What changed |
|---|---|
Threshold LWE layers |
new derivation of the flooding noise ( |
|
defaults: binary ciphertexts, key shares and partial decryptions
( |
MCFE Ring-LWE and dense-LWE families |
labels are hashed with |
|
|
Ring-LWE MIFE / MCFE |
parameters sized for messages of norm |
Ring-LWE family, dense-LWE MCFE keys, |
exact Gaussian sampling (FACCT) by default, recorded in the public
parameters; |
Re-keying¶
Deployment |
What to do |
|---|---|
|
finish with 0.3.0 only the rounds that must finish (with |
|
generate keys again (the cached record is regenerated) |
pairing-based schemes with 0.3.0 keys |
generate keys on BLS12-381, or keep |
other schemes |
keys and ciphertexts of 0.3.0 keep working; regenerating them is still the safe choice, since serialized formats can change between versions of this research prototype |
Tooling¶
requirements.txtis removed:pyproject.tomllists the dependencies (pip install -e ".[test]"); PyYAML is no longer needed.Dockerfile.pairingmoved todocker/Dockerfile.pairing; the parameter estimators totools/params/.The benchmark scripts are commands of
benchmarks/run.py(python benchmarks/run.py --help), with the same options.The tests moved into one directory per topic, with pytest marks for the groups (
CONTRIBUTING.md).