For App DevelopersΒΆ
This guide provides application developers with the essential information needed to integrate Charm cryptographic schemes into their applications.
Installation and Dependencies
See Platform Install Manual for installation instructions.
Using a Scheme
To use any of our existing schemes in your application, each scheme includes a main
routine that runs through every algorithm (with sample inputs) defined for that scheme.
Thus, the main function provides a test that the scheme works in addition to
demonstrating how to use it.
Example: Instantiating the Cramer-Shoup public-key encryption scheme:
from charm.schemes.pkenc.pkenc_cs98 import CS98
from charm.toolbox.eccurve import prime192v1
from charm.toolbox.ecgroup import ECGroup
groupObj = ECGroup(prime192v1)
pkenc = CS98(groupObj)
(pk, sk) = pkenc.keygen()
M = b'Hello World!'
ciphertext = pkenc.encrypt(pk, M)
message = pkenc.decrypt(pk, sk, ciphertext)
For a full list of schemes available, see the Implemented Schemes section. For adapters that extend scheme functionality (such as hybrid encryption), see the Scheme Adapters section.
Using the Serialization API
To support serialization of key material and ciphertexts, we provide two high-level API calls to serialize Charm objects embedded in arbitrary Python structures (e.g., lists, tuples, or dictionaries):
objectToBytes()- Converts Charm objects to base64-encoded byte stringsbytesToObject()- Reconstructs Charm objects from serialized byte strings
Both functions are available from the charm.core.engine.util package and require:
The object to be serialized/deserialized
A class that defines
serializeanddeserializemethods (such as a group object)
Basic Usage Example:
The following example demonstrates serialization with any supported group object
(IntegerGroup, PairingGroup, or ECGroup):
from charm.core.engine.util import objectToBytes, bytesToObject
# Serialize a public key to bytes
pk_bytes = objectToBytes(pk, group)
# Deserialize back to original object
orig_pk = bytesToObject(pk_bytes, group)
Custom Serialization Example:
For schemes based on IntegerGroup that do not utilize a group object, you can
define a custom serialization class:
from charm.core.math.integer import integer, serialize, deserialize
class MySerializeAPI:
def __init__(self):
pass
def serialize(self, charm_object):
assert type(charm_object) == integer, \
f"required type is integer, not: {type(charm_object)}"
return serialize(charm_object)
def deserialize(self, data):
assert type(data) == bytes, \
f"required type is bytes, not: {type(data)}"
return deserialize(data)
Then use your custom serializer with the standard API:
from charm.core.engine.util import objectToBytes, bytesToObject
serObject = MySerializeAPI()
pk_bytes = objectToBytes(pk, serObject)
orig_pk = bytesToObject(pk_bytes, serObject)
Using Charm in C/C++ Applications
Charm provides a C interface to facilitate integration with C/C++ applications. While this feature is still in development, it enables you to use Charm cryptographic schemes directly from native code.
The C API provides the following key functions:
InitializeCharm()/CleanupCharm()- Initialize and tear down the Charm environmentInitPairingGroup(curve)- Initialize a pairing group with the specified curveInitClass(module, class, group)- Load a Charm scheme classCallMethod(obj, method, format, ...)- Call a method on a Charm objectGetIndex(obj, idx)- Extract an element from a tuple or listFree(obj)- Release a Charm object
Example: Using the BSW07 CP-ABE scheme from C:
/* Charm C interface header */
#include "charm_embed_api.h"
Charm_t *module, *group, *class;
/* Initialize Charm environment */
InitializeCharm();
/* Initialize a pairing group */
group = InitPairingGroup("SS1024");
/* Initialize the CP-ABE scheme */
class = InitClass("abenc_bsw07", "CPabe_BSW07", group);
/* Call setup algorithm */
Charm_t *master_keys = CallMethod(class, "setup", "");
Charm_t *pkDict = GetIndex(master_keys, 0);
Charm_t *mskDict = GetIndex(master_keys, 1);
/* Call keygen algorithm with attributes */
Charm_t *skDict = CallMethod(class, "keygen", "%O%O%A",
pkDict, mskDict, "[ONE, TWO, THREE]");
/* Generate a random message in GT */
Charm_t *msg = CallMethod(group, "random", "%I", GT);
/* Call encrypt algorithm with access policy */
Charm_t *ctDict = CallMethod(class, "encrypt", "%O%O%s",
pkDict, msg,
"((THREE or ONE) and (THREE or TWO))");
/* Call decrypt to recover message */
Charm_t *msg2 = CallMethod(class, "decrypt", "%O%O%O",
pkDict, skDict, ctDict);
/* Process the Charm objects as needed */
/* ... see source for details ... */
/* Free all objects */
Free(module);
Free(group);
Free(class);
Free(master_keys);
Free(pkDict);
Free(mskDict);
Free(skDict);
Free(msg);
Free(msg2);
/* Tear down the environment */
CleanupCharm();
The complete example can be found in test.c in the embed directory of the Charm source.
Contact
Feel free to send us suggestions, bug reports, issues, and scheme implementation experiences at jakinye3@jhu.edu.