Crate hohibe

source ·
Expand description

Implementation of Hierarchical Identity Based Encryption (HIBE), an extension of Identity Based Encryption (IBE).

⚠️ Warning: Cryptographic Hazmat ☣️

This crate is made for playing around with HIBE and for prototyping of applications and protocols using HIBE. It has not been audited, it is not battle tested, and nobody claims it to be secure.

Use it at your own risk and if you know what you are doing!

Introduction

HIBEs are encryption schemes in which a party can encrypt data for a given recipient by using the recipient’s identity in the encryption process, instead of requiring an explicitely shared public key. In addition, the hierarchical property allows holders of a secret key for an identity to also generate the keys of subordinate identities.

This library is intended to provide an easy-to-use implementation of HIBE for prototyping and playing around. The library is not optimized for speed, but rather for usability (for example, it requires the standard library and allocations, and it unconditionally requires serde for serialization).

Example

For this example, we assume that we are dealing with domains. The root identity is the complete domain namespace, then the TLDs follow, down to the actual domain. We set 3 to be the maximum depth, just for illustratory purposes.

use hohibe::kem::HybridKem;

const MAX_DEPTH: usize = 3;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut rng = rand::thread_rng();
    let kem = HybridKem::new(MAX_DEPTH);
    let (public_key, master_secret) = kem.setup(&mut rng)?;

    // Encrypt for hibe.example.com
    let ciphertext = kem.encrypt(&mut rng, &public_key, &["com", "example", "hibe"], b"GET /")?;

    // Assume that the owner of example.com is given the secret key for their domain ...
    let example_com = kem.generate_key(
        &mut rng,
        &public_key,
        &master_secret,
        &["com", "example"],
    )?;
    // ... and they can use that to derive the key for the subdomain
    let secret_key = kem.derive_key(
        &mut rng,
        &public_key,
        &example_com,
        &["com", "example", "hibe"],
    )?;

    // Now we can decrypt
    let plaintext = kem.decrypt(&public_key, &secret_key, &ciphertext)?;

    assert_eq!(plaintext, b"GET /");

    Ok(())
}

Crate Structure

The hibe submodule contains the basic definitions of HIBE functionality, as hibe::Hibe (basic parameter and key generation), hibe::HibeKem (HIBE key encapsulation) and hibe::HibeCrypt (HIBE encryption). Those methods work directly on the group elements, as they are defined in their respective papers.

To aid in using those algorithms, a higher-level wrapper is provided in the kem submodule, mainly in the kem::HybridKem struct. This allows you to deal with bytes instead of group elements.

The bridge between hibe and kem is provided by Mapper, which translates from arbitrary identities from the application domain to the low-level, mathematical representation of identities in the context of HIBEs.

Currently, kem::HybridKem is hardwired to hibe::BonehBoyenGoh to keep the amount of generics and generic bounds low. This might change in the future, when more HIBEs might be implemented.

Implemented Algorithms

Currenly, this crate implements the HIBE of Boneh, Boyen and Goh, “Hierarchical Identity Based Encryption with Constant Size Ciphertext” (eprint). This algorithm lives as hibe::BonehBoyenGoh.

The algorithms in this crate are implemented on top of bls_12_381_plus, as it provides better serde support and access to the internals of the group elements.

Modules

  • Error definitions for HIBE operations.
  • Low-level implementation of HIBE primitives.
  • High-level wrapper around HIBE operations.

Traits

  • A trait to provide byte-level access to objects.
  • A trait to mark objects that can map from an application-specific identity to a HIBE-specific identity.