Package: hybrid-pke
Hybrid PKEThe Hybrid Public Key Encryption (HPKE) standard in Python.hybrid_pke=hpke-rs:heavy_plus_sign:PyO3This library provides Python bindings to thehpke-rscrate, which supports primitives from eitherRust CryptoorEverCrypt.Table of ContentsUsageFeaturesInstallationDevelopmentRelated ProjectsUsageBasicThe single-shot API is intended for single message encryption/decryption. The default HPKE configuration uses the unauthenticated Base mode, an X25519 DH key encapsulation mechanism, a SHA256 key derivation mechanism, and a ChaCha20Poly1305 AEAD function.importhybrid_pkehpke=hybrid_pke.default()info=b""# shared metadata, correspondance-levelaad=b""# shared metadata, message-levelsecret_key_r,public_key_r=hpke.generate_key_pair()# receiver keys, pre-generated# ============== Sender ==============message=b"hello from the other side!"encap,ciphertext=hpke.seal(public_key_r,info,aad,message)# ============= Receiver =============plaintext=hpke.open(encap,secret_key_r,info,aad,ciphertext)print(plaintext.decode("utf-8"))# >> hello from the other side!AdvancedSender & Receiver ContextsThe Sender Context and Receiver Context APIs allow for setting up a context for repeated encryptions and decryptions. It's recommended whenever you intend to perform several encryptions or decryptions in quick succession.info=b"quotes from your favorite aphorists"aads=[b"Szasz",b"Nietzsche",b"Morandotti",b"Brudzinski",b"Hubbard",]# ============== Sender ==============messages=[b"Two wrongs don't make a right, but they make a good excuse.",b"Become who you are!",b"Only those who aren't hungry are able to judge the quality of a meal.",b"Under certain circumstances a wanted poster is a letter of recommendation.",b"Nobody ever forgets where he buried the hatchet.",]encap,sender_context=hpke.setup_sender(public_key_r,info)ciphertexts=[]foraad,msginzip(aads,messages):ciphertext=sender_context.seal(aad,msg)ciphertexts.append(ciphertext)# ============= Receiver =============receiver_context=hpke.setup_receiver(encap,secret_key_r,info)plaintexts=[]foraad,ctxtinzip(aads,ciphertexts):plaintext=receiver_context.open(aad,ctxt)plaintexts.append(plaintext)print(f"\"{plaintexts[0].decode()}\"-{aad[0].decode()}")print(f"\"{plaintexts[1].decode()}\"-{aad[1].decode()}")# >> "Two wrongs don't make a right, but they make a good excuse." - Szasz# >> "Become who you are!" - NietzscheMode.AUTH: Authenticated SenderAuth mode allows for signing and verifying encryptions with a previously authenticated sender key-pair.hpke=hybrid_pke.default(mode=hybrid_pke.Mode.AUTH)secret_key_r,public_key_r=hpke.generate_key_pair()# receiver keyssecret_key_s,public_key_s=hpke.generate_key_pair()# sender keys, pre-authenticated# ============== Sender ==============# sign with sender's secret keyencap,ciphertext=hpke.seal(public_key_r,info,aad,message,sk_s=secret_key_s)# ============= Receiver =============# verify with sender's public keyplaintext=hpke.open(encap,secret_key_r,info,aad,ciphertext,pk_s=public_key_s)Mode.PSK: Pre-shared Key AuthenticationPSK mode allows for signing and verifying encryptions with a previously shared key held by both the sender and recipient.hpke=hybrid_pke.default(mode=hybrid_pke.Mode.PSK)# pre-shared key + IDpsk=bytes.fromhex("0247fd33b913760fa1fa51e1892d9f307fbe65eb171e8132c2af18555a738b82")psk_id=bytes.fromhex("456e6e796e20447572696e206172616e204d6f726961")# ============== Sender ==============# sign with pre-shared keyencap,ciphertext=hpke.seal(public_key_r,info,aad,message,psk=psk,psk_id=psk_id)# ============= Receiver =============# verify with pre-shared keyplaintext=hpke.open(encap,secret_key_r,info,aad,ciphertext,psk=psk,psk_id=psk_id)Mode.AUTH_PSK: Combining AUTH and PSK.PSK mode allows for signing and verifying encryptions with a previously shared key held by both the sender and recipient.hpke=hybrid_pke.default(mode=hybrid_pke.Mode.PSK)secret_key_r,public_key_r=hpke.generate_key_pair()# receiver keyssecret_key_s,public_key_s=hpke.generate_key_pair()# sender keys, pre-authenticated# pre-shared key + IDpsk=bytes.fromhex("0247fd33b913760fa1fa51e1892d9f307fbe65eb171e8132c2af18555a738b82")psk_id=bytes.fromhex("456e6e796e20447572696e206172616e204d6f726961")# ============== Sender ==============# sign with both pre-shared key and sender's secret keyencap,ciphertext=hpke.seal(public_key_r,info,aad,message,psk=psk,psk_id=psk_id,sk_s=secret_key_s,)# ============= Receiver =============# verify with both pre-shared key and sender's public keyplaintext=hpke.open(encap,secret_key_r,info,aad,ciphertext,psk=psk,psk_id=psk_id,pk_s=public_key_s,)(back to top)FeaturesThe features available match those supported byhpke-rs.HPKE Modesmode_basemode_pskmode_authmode_auth_pskKEMs: (Diffie-Hellman) Key Encapsulation MechanismsDHKEM(P-256, HKDF-SHA256)DHKEM(P-384, HKDF-SHA384)DHKEM(P-521, HKDF-SHA512)DHKEM(X25519, HKDF-SHA256)DHKEM(X448, HKDF-SHA512)KDFs: Key Derivation FunctionsHKDF-SHA256HKDF-SHA384HKDF-SHA512AEADs: Authenticated Encryption with Additional Data functionsAES-128-GCMAES-256-GCMChaCha20Poly1305Export only(back to top)InstallationWheels for various platforms and architectures can be found onPyPIor in thewheelhouse.ziparchive from thelatest Github release.The library can also be installed from source withmaturin-- see below.(back to top)DevelopmentWe usematurinto build and distribute the PyO3 extension module as a Python wheel.For users ofcmake, we provide aMakefilethat includes some helpful development commands.Some useful tipsmaturin developbuilds & installs the Python package into your Python environment (venvorcondarecommended)pytest .tests the resulting Python package.pytest -n auto .runs the full test suite in parallel.maturin build --release -o dist --sdistbuilds the extension module in release-mode and produces a wheel for your environment's OS and architecture.The-i/--interpreterflag formaturincan be used to swap out different Python interpreters, if you have multiple Python installations.(back to top)Related Projectshpke-py: An implementation of HPKE based on primitives fromcryptography.io.(back to top)