Repository navigation
libpep 0.13.0
The companion release of the n-PEP paper (STM 2026). This is a large clean-up of the public API ahead of 1.0: the layout is settled, names are consistent, the bindings live in their own crates, and the command-line tool covers the whole library. Everything ships as before: libpep on crates.io, libpep-py on PyPI and @nolai/libpep-wasm on npm.
Highlights
- Module layout. The low-level layer is now
elgamal(ciphertext, primitives, arithmetic);contextsholdsPseudonymizationDomainandEncryptionContext;factorsis split intotypes,secretsandderivation. The Python and WASM bindings mirror this, including alibpep.contextssubmodule. - One name per type.
PseudonymizationInfo,PseudonymRekeyInfo,AttributeRekeyInfoandTranscryptionInfoare structs instead of aliases of factor types. A factor is a single scalar operand; an info is what a transcryptor computes for one transcryption between two contexts. - Explicit keys. Key types no longer convert implicitly from raw scalars or group elements. Use
SecretKey::from_scalarandPublicKey::from_point, and derive a public key withSecretKey::public_key(). Secret material no longer dereferences to its scalar; read it withvalue(). - Distributed setup material is not a key. Blinding factors, blinded global secret keys and session key shares have their own traits (
BlindedGlobalSecretKey,SessionKeyShare) and no longer implementSecretKey.BlindedGlobalKeysis renamedBlindedGlobalSecretKeys. - Bindings as workspace crates under
bindings/pythonandbindings/wasm. Thepythonandwasmcargo features are gone; the core crate is a plain rlib. Python ships PEP 561 type stubs. peppyrewritten. A noun/verb command tree (keys,factors,pseudonym,attribute,json,elgamal,scalar,point) with named options,-and@fileinputs,--jsonoutput, exit codes instead of panics, shell completions and a man page. It now covers attribute keys, the full distributed flow, factor derivation and all primitives including the transitive*2variants.- README rewritten around a quick start that runs as a doctest, with the relation to OPRFs (RFC 9497) and proxy re-encryption spelled out.
Fixes
- Every feature combination compiles; CI covers
insecureand no-default-features builds and a depth-2 feature powerset. - Offline (global-key) decryption paths in the Python bindings are fixed and tested.
- Decrypting corrupted or wrong-key JSON no longer panics; it returns
JsonError(ValueError/JsErrorin the bindings). - Long values perform one scalar inversion per rekey instead of one per block.
BatchErrorgains aDecryptionFailedvariant.
Upgrading from 0.12
| 0.12 | 0.13 |
|---|---|
libpep::core::*, libpep::arithmetic::* |
libpep::elgamal::*, libpep::elgamal::arithmetic::* |
libpep::factors::contexts::* |
libpep::contexts::* |
PseudonymRSKFactors |
PseudonymizationInfo |
info.k on a rekey info (was the factor itself) |
info.k on PseudonymRekeyInfo { k } / AttributeRekeyInfo { k } |
PseudonymSessionSecretKey::from(scalar) and friends |
::from_scalar(scalar); public keys ::from_point(point) |
*secret_key (Deref) |
secret_key.value() |
BlindedGlobalKeys |
BlindedGlobalSecretKeys |
factors::secrets::make_*_factor |
factors::make_*_factor (defined in factors::derivation) |
RekeyInfoProvider, MakeSessionKeyShare |
removed |
Python info.rev() |
info.reverse() |
Python from libpep.factors import EncryptionContext |
from libpep.contexts import EncryptionContext |
Python Transcryptor.pseudonym_rekey_info() returned a factor |
returns PseudonymRekeyInfo; rekey() takes it |
peppy generate-global-keys, peppy encrypt, … |
peppy keys global generate, peppy pseudonym encrypt, … (see peppy --help) |
Dependencies: curve25519-dalek 5.0, sha2 0.11, hmac 0.13, pyo3 0.29. MSRV is 1.85.