hibe

package
v2.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2023 License: Apache-2.0, BSD-3-Clause Imports: 5 Imported by: 1

README

Implementation of Hierarchical Identity-Based Encryption

This is an implementation in Go of the Hierarchical Identity-Based Encryption system described in the paper "Hierarchical Identity Based Encryption with Constant Size Ciphertext" by Boneh, Boyen, and Goh.

Documentation

Overview

Package hibe implements the cryptosystem described in the paper "Hierarchical Identity Based Encyprtion with Constant Size Ciphertext" by Boneh, Boyen, and Goh.

The algorithms call for us to use a group G that is bilinear, i.e, there exists a bilinear map e: G x G -> G2. However, the bn256 library uses a slightly different definition of bilinear groups: it defines it as a triple of groups (G2, G1, GT) such that there exists a bilinear map e: G2 x G1 -> GT. The paper calls this an "asymmetric bilinear group".

It turns out that we are lucky. Both G2 and G1, as implemented in bn256 share the same order, and that that order (bn256.Order) happens to be a prime number p. Therefore G2 and G1 are both isomorphic to Zp. This is important for two reasons. First, the algorithm requires G to be a cyclic group. Second, this implies that G2 and G1 are isomorphic to each other. This means that as long as we are careful, we can use this library to carry out a computation that is logically equivalent to the case where G2 and G1 happen to be the same group G.

For simplicity, take G = G2. In other words, choose the G used in Boneh's algorithms to be the group G2 provided by bn256.

In order for this work, we need to choose a single isomorphism phi: G2 -> G1 and stick with it for all operations. Let g1 be the base of G2, and g2 be the base of G1, as provided via the APIs of bn256. We define phi as follows: phi(g1 ^ a) = g2 ^ a, for all a in Z. This is well defined because G2 is isomorphic to Zp, a cyclic group.

What this means is that, if we are working with some x in G to implement the algorithm, then we must do so using g1 ^ k in G2 and g2 ^ k in G1, where g1 ^ k = x. Using this method, we can emulate the requirements of Boneh's algorithm.

Furthermore, note that a marshalled G1 element is 64 bytes, whereas a marshalled G2 element is 128 bytes. Therefore, we actually switch the order of arguments to the bilinear map e so that marshalled parameters and keys are smaller (since otherwise, more elements are passed as the secone argument and therefore take up a lot of space). Note that switching the order of arguments to a bilinear map (asymmetric or otherwise) maintains bilinearity.

One more thing to note is that the group, as described in the paper, is multiplicative, whereas the bn256 library uses additive notation. Keep this in mind if you ever need to read through the code.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Decrypt

func Decrypt(key *PrivateKey, ciphertext *Ciphertext) *bn256.GT

Decrypt recovers the original message from the provided ciphertext, using the provided private key.

func HashToGT

func HashToGT(bytestring []byte) *bn256.GT

HashToGT hashes a byte slice to a group element in GT.

func HashToZp

func HashToZp(bytestring []byte) *big.Int

HashToZp hashes a byte slice to an integer in Zp*.

func Setup

func Setup(random io.Reader, l int) (*Params, MasterKey, error)

Setup generates the system parameters, (hich may be made visible to an adversary. The parameter "l" is the maximum depth that the hierarchy will support.

Types

type Ciphertext

type Ciphertext struct {
	A *bn256.GT
	B *bn256.G2
	C *bn256.G1
}

Ciphertext represents an encrypted message.

func Encrypt

func Encrypt(random io.Reader, params *Params, id []*big.Int, message *bn256.GT) (*Ciphertext, error)

Encrypt converts the provided message to ciphertext, using the provided ID as the public key.

func (*Ciphertext) Marshal

func (ciphertext *Ciphertext) Marshal() []byte

Marshal encodes the ciphertext as a byte slice.

func (*Ciphertext) Unmarshal

func (ciphertext *Ciphertext) Unmarshal(marshalled []byte) (*Ciphertext, bool)

Unmarshal recovers the ciphertext from an encoded byte slice.

type MasterKey

type MasterKey *bn256.G1

MasterKey represents the key for a hierarchy that can create a key for any element.

type Params

type Params struct {
	G  *bn256.G2
	G1 *bn256.G2
	G2 *bn256.G1
	G3 *bn256.G1
	H  []*bn256.G1

	// Some cached state
	Pairing *bn256.GT
}

Params represents the system parameters for a hierarchy.

func (*Params) Marshal

func (params *Params) Marshal() []byte

Marshal encodes the parameters as a byte slice.

func (*Params) MaximumDepth

func (params *Params) MaximumDepth() int

MaximumDepth returns the maximum depth of the hierarchy. This was specified via the "l" argument when Setup was called.

func (*Params) Precache

func (params *Params) Precache()

Precache forces "cached params" to be computed. Normally, they are computed on the fly, but that is not thread-safe. If you plan to call functions (especially Encrypt) multiple times concurrently, you should call this first, to eliminate race conditions.

func (*Params) Unmarshal

func (params *Params) Unmarshal(marshalled []byte) (*Params, bool)

Unmarshal recovers the parameters from an encoded byte slice.

type PrivateKey

type PrivateKey struct {
	A0 *bn256.G1
	A1 *bn256.G2
	B  []*bn256.G1
}

PrivateKey represents a key for an ID in a hierarchy that can decrypt messages encrypted with that ID and issue keys for children of that ID in the hierarchy.

func KeyGenFromMaster

func KeyGenFromMaster(random io.Reader, params *Params, master MasterKey, id []*big.Int) (*PrivateKey, error)

KeyGenFromMaster generates a key for an ID using the master key.

func KeyGenFromParent

func KeyGenFromParent(random io.Reader, params *Params, parent *PrivateKey, id []*big.Int) (*PrivateKey, error)

KeyGenFromParent generates a key for an ID using the private key of the parent of ID in the hierarchy. Using a different parent will result in undefined behavior.

func (*PrivateKey) DepthLeft

func (privkey *PrivateKey) DepthLeft() int

DepthLeft returns the maximum depth of descendants in the hierarchy whose keys can be generated from this one.

func (*PrivateKey) Marshal

func (key *PrivateKey) Marshal() []byte

Marshal encodes the private key as a byte slice.

func (*PrivateKey) Unmarshal

func (key *PrivateKey) Unmarshal(marshalled []byte) (*PrivateKey, bool)

Unmarshal recovers the private key from an encoded byte slice.

Directories

Path Synopsis
Package bn256 implements a particular bilinear group.
Package bn256 implements a particular bilinear group.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL