proxy-recrypt
Unidirectional proxy re-encryption for Python. proxy-recrypt wraps the
JHU-MIT Proxy Re-encryption Library (proxylib)
— the reference implementation of the AFGH "PRE1" scheme (Ateniese, Fu,
Green, Hohenberger — NDSS'05) over the MIRACL pairing library — and adds a
Pythonic high-level API plus a hybrid (KEM/DEM) layer so you can encrypt data
of any size: Alice encrypts once, hands a re-encryption key to a
semi-trusted proxy, and the proxy transforms her ciphertexts so Bob can
decrypt them — without the proxy ever seeing plaintexts or secret keys.
Install
Linux x86-64 only. Requirements: g++, ar, Python ≥ 3.9 with setuptools
and the CPython development headers.
./build_native.sh # builds miracl.a + proxylib.a (with -fPIC) and the extension
python -m pip install .
build_native.sh also leaves an in-place build in proxy_recrypt/, so the
tests and example run from the source tree without installing:
python3 tests/test_proxy_recrypt.py # or: pytest tests/test_proxy_recrypt.py
python3 example/example.py
If Python.h is not in your compiler's default include path, either export
CPATH (e.g. export CPATH=$HOME/.local/include/python3.12) before
building, or place the headers in ~/.local/include/pythonX.Y/ — setup.py
picks that directory up automatically. The high-level hybrid API depends on
cryptography (installed
automatically by pip install .).
Quick start
import proxy_recrypt as prc
# One-time setup: parameters shared by all users.
params = prc.generate_params()
alice_pk, alice_sk = prc.generate_keypair(params)
bob_pk, bob_sk = prc.generate_keypair(params)
# Alice encrypts data of any size for herself:
# capsule = tiny re-encryptable encryption of a fresh 32-byte data key
# payload = AES-256-GCM encryption of the data under that key
data = b"any amount of data" * 10_000
capsule, payload = prc.encrypt_data(params, alice_pk, data)
# Alice delegates to Bob: the proxy gets this key (works Alice->Bob only).
rekey = prc.generate_reencryption_key(params, bob_pk, alice_sk)
# The proxy transforms ONLY the capsule; the payload is untouched.
capsule_bob = prc.reencrypt_capsule(params, capsule, rekey)
# Bob decrypts with his own secret key.
assert prc.decrypt_data(params, bob_sk, capsule_bob, payload) == data
Short messages (≤ 63 bytes) can skip the hybrid layer:
encrypt_message(params, pk, msg, level=2) / reencrypt(params, ct, rekey) /
decrypt_message(params, sk, ct).
Everything serializes to bytes: params.to_bytes(), pk.to_bytes(),
sk.to_bytes(), ct.to_bytes() with matching *_from_bytes() functions;
re-encryption keys, capsules and payloads already are bytes. In a fresh
process, always load CurveParams first.
API
High-level
| Function | Description |
|---|---|
generate_params() -> CurveParams |
Generate the shared curve parameters. |
generate_keypair(params) -> (PK_PRE1, SK_PRE1) |
Generate a keypair. |
encrypt_data(params, pk, data, aad=None) -> (capsule, payload) |
Hybrid encryption of arbitrary-size data (level-2 KEM capsule + AES-256-GCM payload). |
decrypt_data(params, sk, capsule, payload, aad=None) -> bytes |
Decrypt as owner or delegatee (handles re-encrypted capsules). |
reencrypt_capsule(params, capsule, rekey) -> bytes |
Proxy-side capsule transform, bytes in / bytes out. |
encrypt_message(params, pk, message, level=2) -> Ciphertext_PRE1 |
Direct PRE1 encryption of ≤ 63 bytes (level 1 = not re-encryptable, 2 = re-encryptable). |
decrypt_message(params, sk, ciphertext) -> bytes |
Direct PRE1 decryption. |
generate_reencryption_key(params, delegatee_pk, delegator_sk) -> bytes |
Unidirectional re-encryption key delegator→delegatee. |
reencrypt(params, ciphertext, rekey) -> Ciphertext_PRE1 |
Proxy-side transform of a second-level ciphertext. |
Low-level (mapping to proxylib)
| proxy_recrypt | proxylib (C++) |
|---|---|
PRE1_generate_params(params) |
PRE1_generate_params(CurveParams&) |
PRE1_keygen(params, pk, sk) |
PRE1_keygen(...) |
PRE1_level1_encrypt(params, msg, pk) |
encodePlaintextAsBig + PRE1_level1_encrypt(...) |
PRE1_level2_encrypt(params, msg, pk) |
encodePlaintextAsBig + PRE1_level2_encrypt(...) |
PRE1_delegate(params, delegatee_pk, delegator_sk) |
PRE1_delegate(...) + SerializeDelegationKey_PRE1 |
PRE1_reencrypt(params, ct, rekey) |
DeserializeDelegationKey_PRE1 + PRE1_reencrypt(...) |
PRE1_decrypt(params, ct, sk) |
PRE1_decrypt(...) + plaintext decode |
X.to_bytes() / X_from_bytes(b) |
serialize() / deserialize() with SERIALIZE_BINARY |
Ciphertext_PRE1.type |
CIPHERTEXT_TYPE (CIPH_FIRST_LEVEL/CIPH_SECOND_LEVEL/CIPH_REENCRYPTED) |
Errors: bad arguments and malformed serialized data raise ValueError;
proxylib failures raise RuntimeError; GCM authentication failures (tamper,
wrong key, aad mismatch) raise cryptography.exceptions.InvalidTag; an RNG
seeding failure at import raises ImportError.
Caveats
- Legacy parameters. proxylib (2007) uses a 512-bit prime-field pairing curve with a 160-bit group order — far below current security recommendations for pairing-based crypto. Treat this package as a research and prototyping tool, not production-grade cryptography.
- Not wire-compatible with the JavaScript
proxy-recryptpackage. The hybrid capsule/payload structure mirrors it, but the curve, ciphertext serialization and KDF differ, so blobs cannot be exchanged between the two. - Direct-message encoding.
encrypt_messageplaintexts are encoded as big integers, so leadingb"\x00"bytes are not preserved bydecrypt_message(the hybrid API is not affected). - Single parameter set per process; not thread-safe. MIRACL/proxylib
keep the active curve and scratch state in globals — use one
CurveParamsat a time and keep all calls on one thread. - License. proxylib is published for research and non-commercial use
(see the headers in
external/proxylib/); this package inherits those constraints.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file proxy_recrypt-1.0.0.tar.gz.
File metadata
- Download URL: proxy_recrypt-1.0.0.tar.gz
- Upload date:
- Size: 2.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7636efc21722ac17b5f49839c5c602bf95b20766ffb0b344b5971e2b3564fb1
|
|
| MD5 |
36a1835b1785361eae14f9663a4fc048
|
|
| BLAKE2b-256 |
7d0f14dbeaa17b7ef30826f205092570a3b452d3284349b18cd9db4af720bf4f
|
File details
Details for the file proxy_recrypt-1.0.0-cp312-cp312-manylinux_2_38_x86_64.whl.
File metadata
- Download URL: proxy_recrypt-1.0.0-cp312-cp312-manylinux_2_38_x86_64.whl
- Upload date:
- Size: 698.1 kB
- Tags: CPython 3.12, manylinux: glibc 2.38+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a5058e8cd98f34c569f1ce5785f2dc34e67409db6f04f44041ad2d6cc91c7c7
|
|
| MD5 |
c21c9ae7c12c1536d35afdbf0f91318e
|
|
| BLAKE2b-256 |
dd511f3b145930add33be34e4de66a60dbc80b93270c7ad567846f1791b50f38
|