Crates.io | cosmian_cover_crypt |
lib.rs | cosmian_cover_crypt |
version | 14.0.0 |
source | src |
created_at | 2022-10-10 10:36:41.152614 |
updated_at | 2024-03-07 11:12:14.446578 |
description | Key Policy attribute encryption based on subset cover |
homepage | |
repository | https://github.com/Cosmian/cover_crypt |
max_upload_size | |
id | 684497 |
size | 883,695 |
Implementation of the CoverCrypt algorithm which allows creating ciphertexts for a set of attributes and issuing user keys with access policies over these attributes.
See examples/runme.rs
for a code sample that
introduces the main CoverCrypt functionalities. It can be run using
cargo run --example runme
.
To build the core only, run:
cargo build --release
To build everything:
cargo build --release --all-features
The code contains numerous tests that you can run using:
cargo test --release --all-features
Benchmarks can be run using (one can pass any feature flag):
bash ./benches/generate.sh
In CoverCrypt, messages are encrypted using a symmetric scheme. The right management is performed by a novel asymmetric scheme used to encapsulate a symmetric key for a set of attributes. This encapsulation is stored in an object called encrypted header, along with the symmetric ciphertext.
This design brings several advantages:
CoverCrypt encryption is post-quantum secure (with a post-quantum security level of 128 bits):
The CoverCrypt scheme also ensures that:
Asymmetric keys must be generated beforehand. This is the role of a central authority, which is in charge of:
The CoverCrypt API exposes 4 functions:
CoverCrypt::generate_master_keys
: generate master keysCoverCrypt::update_master_keys
: update the master keysCoverCrypt::generate_user_secret_key
: create a user secret keyCoverCrypt::refresh_user_secret_key
: update a user secret keyThe key generations may be long if the policy contains many rights or if there are many users. But this is usually run once at setup. Key update and refresh stay fast if the changes are small.
CoverCrypt is an attribute-based encryption algorithm. This means that an
encrypted header produced for the attributes France
and Top Secret
can only
be decrypted by the user holding a key corresponding to these attributes.
In order to transform this high-level view into encapsulations, the following objects are defined:
When generating the master keys, the global policy is converted into the set of all possible partitions and a keypair is generated for each one of these partitions. The master public key holds all the public key of all these keypairs and the master secret key holds the secret key of all these keypairs.
When encrypting for a given encryption policy, this policy is converted into a set of partitions. Then, one key encapsulation is generated per partition using the corresponding public sub-key in the master public key.
Similarly, when generating a user secret key for a given user policy, this policy is converted into the set of corresponding partitions and the user receives the secret sub-key associated to each partitions.
Example: the following policy is composed of two axes. The Security
axis
composed of three attributes and the Country
axis composed of 4 attributes.
Policy: {
Security: { // <- first axis
None,
Medium,
High
},
Country: { // <- second axis
France,
Germany,
UK,
Spain
}
}
The encryption policy Security::Medium && ( Country::France || Country::Spain)
would be converted into two partitions. The encryption policy
Security::High
would be expanded into Security::High && (Country::France || ... || Country::Spain)
then converted into 4 partitions.
The size of the serialized keys and encapsulation is given by the following formulas:
where:
NOTE: For our implementation CoverCryptX25519Aes256
:
This is the core of the CoverCrypt scheme. It allows creating a symmetric key and its encapsulation for a given set of rights.
To ease the management of the encapsulations, an object EncryptedHeader
is
provided in the API. An encrypted header holds an encapsulation and a symmetric
ciphertext of an optional additional data. This additional data can be useful
to store metadata.
Classic implementation sizes:
Nb. of partitions | Encapsulation size (in bytes) | User decryption key size (in bytes) |
---|---|---|
1 | 130 | 98 |
2 | 163 | 131 |
3 | 196 | 164 |
4 | 229 | 197 |
5 | 262 | 230 |
Post-quantum implementation sizes:
Nb. of partitions | Encapsulation size (in bytes) | User decryption key size (in bytes) |
---|---|---|
1 | 1186 | 1250 |
2 | 2275 | 2435 |
3 | 3364 | 3620 |
4 | 4453 | 4805 |
5 | 5542 | 5990 |
Note: encapsulations grow bigger with the size of the target set of rights and so does the encapsulation time.
A user can retrieve the symmetric key needed to decrypt a CoverCrypt ciphertext
by decrypting the associated EncryptedHeader
. This is only possible if the
user secret keys contains the appropriate rights.
The benchmarks presented in this section are run on a Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz.
A formal description and proof of the CoverCrypt scheme is given in this paper. It also contains an interesting discussion about the implementation.
The developer documentation can be found on doc.rs