Source code for pkenc_adapt_hybrid

'''
**Hybrid Encryption Adapter for PKE (PKE Hybrid)**

*Description:* Converts a Public Key Encryption scheme into a hybrid encryption
scheme capable of encrypting arbitrary-length messages.

| **Notes:** Uses symmetric encryption (AES) with a randomly generated session key.
| The session key is encrypted using the underlying PKE scheme.
| Works with ElGamal and CS98 schemes.

.. rubric:: Adapter Properties

* **Type:** hybrid encryption adapter
* **Underlying Scheme:** any public key encryption scheme (e.g., ElGamal, CS98)
* **Purpose:** enables PKE schemes to encrypt arbitrary-length byte messages

.. rubric:: Implementation

:Authors: J. Ayo Akinyele
:Date: 2011
'''

# Works for ElGamal and CS98 schemes
from charm.toolbox.PKEnc import PKEnc
from charm.toolbox.securerandom import OpenSSLRand
from charm.toolbox.symcrypto import AuthenticatedCryptoAbstraction
from charm.toolbox.ecgroup import ECGroup
from charm.toolbox.eccurve import prime192v1
from charm.schemes.pkenc.pkenc_cs98 import CS98
from charm.core.crypto.cryptobase import AES
debug = False

# Adapter class for Hybrid Encryption Schemes
[docs] class HybridEnc(PKEnc): """ >>> groupObj = ECGroup(prime192v1) >>> pkenc = CS98(groupObj) >>> hyenc = HybridEnc(pkenc, msg_len=groupObj.bitsize()) >>> (public_key, secret_key) = hyenc.keygen() >>> msg = b'this is a new message' >>> cipher_text = hyenc.encrypt(public_key, msg) >>> decrypted_msg = hyenc.decrypt(public_key, secret_key, cipher_text) >>> decrypted_msg == msg True """ def __init__(self, pkenc, msg_len=16, key_len=16, mode=AES): PKEnc.__init__(self) # check that pkenc satisfies properties of a pkenc scheme if hasattr(pkenc, 'keygen') and hasattr(pkenc, 'encrypt') and hasattr(pkenc, 'decrypt'): self.pkenc = pkenc self.key_len = key_len # 128-bit session key by default self.msg_len = msg_len self.alg = mode if debug: print("PKEnc satisfied.")
[docs] def keygen(self, secparam=None): if secparam == None: # ec module group return self.pkenc.keygen() # integer group return self.pkenc.keygen(secparam)
[docs] def encrypt(self, pk, M): # generate a short session key, K and encrypt using pkenc key = OpenSSLRand().getRandomBytes(self.msg_len) # encrypt session key using PKEnc c1 = self.pkenc.encrypt(pk, key) # use symmetric key encryption to enc actual message c2 = AuthenticatedCryptoAbstraction(key).encrypt(M) if debug: print("Ciphertext...") if debug: print(c2) return { 'c1':c1, 'c2':c2 }
[docs] def decrypt(self, pk, sk, ct): c1, c2 = ct['c1'], ct['c2'] key = self.pkenc.decrypt(pk, sk, c1)[:self.key_len] if debug: print("Rec key =>", key, ", len =", len(key)) msg = AuthenticatedCryptoAbstraction(key).decrypt(c2) if debug: print("Rec msg =>", msg) return msg
[docs] def main(): groupObj = ECGroup(prime192v1) pkenc = CS98(groupObj) hyenc = HybridEnc(pkenc) (pk, sk) = hyenc.keygen() m = b'this is a new message' cipher = hyenc.encrypt(pk, m) orig_m = hyenc.decrypt(pk, sk, cipher) assert m == orig_m, "Failed Decryption" if debug: print("Successful Decryption!!")
if __name__ == "__main__": debug = True main()