Skip to main content

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-recrypt package. 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_message plaintexts are encoded as big integers, so leading b"\x00" bytes are not preserved by decrypt_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 CurveParams at 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

proxy_recrypt-1.0.0.tar.gz (2.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

proxy_recrypt-1.0.0-cp312-cp312-manylinux_2_38_x86_64.whl (698.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.38+ x86-64

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

Hashes for proxy_recrypt-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b7636efc21722ac17b5f49839c5c602bf95b20766ffb0b344b5971e2b3564fb1
MD5 36a1835b1785361eae14f9663a4fc048
BLAKE2b-256 7d0f14dbeaa17b7ef30826f205092570a3b452d3284349b18cd9db4af720bf4f

See more details on using hashes here.

File details

Details for the file proxy_recrypt-1.0.0-cp312-cp312-manylinux_2_38_x86_64.whl.

File metadata

File hashes

Hashes for proxy_recrypt-1.0.0-cp312-cp312-manylinux_2_38_x86_64.whl
Algorithm Hash digest
SHA256 6a5058e8cd98f34c569f1ce5785f2dc34e67409db6f04f44041ad2d6cc91c7c7
MD5 c21c9ae7c12c1536d35afdbf0f91318e
BLAKE2b-256 dd511f3b145930add33be34e4de66a60dbc80b93270c7ad567846f1791b50f38

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page