PQLR
Postquantum Crypto Library by QAPP
PQLR common KEM interface

Typedefs

typedef struct pqlr_kem_st * pqlr_kem
 PQLR KEM algorithm instance handle. More...
 

Functions

PQLR_API size_t pqlr_kem_num_algs (void)
 Obtains the number of available PQLR KEM algorithms. More...
 
PQLR_API size_t pqlr_kem_get_algs (const char **algs, size_t count)
 Fills the provided buffer with names of available KEM algorithms. More...
 
PQLR_API pqlr_kem pqlr_kem_new (const pqlr_alg alg)
 Creates pqlr_kem instance initialized by alg. More...
 
PQLR_API void pqlr_kem_free (pqlr_kem kem)
 Frees pqlr_kem instance and all corresponding resources. More...
 
PQLR_API pqlr_kem pqlr_kem_duplicate (const pqlr_kem kem)
 duplicates the context of pqlr_kem algorithm More...
 
PQLR_API uint32_t pqlr_kem_get_initiator_public_length (const pqlr_kem kem)
 Obtains initiator's public key length for the current pqlr_kem instance. More...
 
PQLR_API uint32_t pqlr_kem_get_initiator_secret_length (const pqlr_kem kem)
 Obtains initiator's secret key length for the current pqlr_kem instance. More...
 
PQLR_API uint32_t pqlr_kem_get_ciphertext_length (const pqlr_kem kem)
 Obtains ciphertext (request) length for the current pqlr_kem instance. More...
 
PQLR_API uint32_t pqlr_kem_get_shared_secret_length (const pqlr_kem kem)
 Obtains shared secret (key) length for the current pqlr_kem instance. More...
 
PQLR_API int pqlr_kem_keygen (const pqlr_kem kem, uint8_t *pk, uint8_t *sk)
 Initial step of key distribution. Generates a key pair for key distribution initiator. More...
 
PQLR_API int pqlr_kem_encap (const pqlr_kem kem, const uint8_t *pk, uint8_t *ciphertext, uint8_t *session_key)
 Second step of key distribution. Encapsulates key on the responder side. More...
 
PQLR_API int pqlr_kem_decap (const pqlr_kem kem, const uint8_t *sk, const uint8_t *ciphertext, uint8_t *session_key)
 Last step of key distribution. Decapsulates key on the initiator side. More...
 

Detailed Description

This module provides post-quantum key encapsulation mechanisms (KEM) for secure key distribution between two parties. The distributed secret is theoretically tolerant to attacks from both quantum and classical computers. Entry point is pqlr_kem_keygen

General usage

Key encapsulation mechanisms consist of sequential function calls on two sides named initiator and responder.

  1. Both sides call pqlr_kem_new, algorithm context is initialized with chosen parameterset
  2. Initiator calls pqlr_kem_keygen, initiator's public and secret keys are generated
  3. Initiator sends public key to responder
  4. Responder calls pqlr_kem_encap, gets encoded request, key
  5. Responder sends request to initiator
  6. Initiator calls pqlr_kem_decap, gets key
  7. Both sides have similar cryptographically secure key
  8. After the KEM is no more needed resources must be freed on both sides by pqlr_kem_free
Note
In client-server applications client can represent initiator side, whereas server represents responder side, or vice versa.

In order to use any PQLR common KEM interface functions, add the following include:

Example code is listed below:

void use_kem_get_algs(void)
{
size_t nalgs = pqlr_kem_num_algs();
const char** kems = malloc(sizeof(const char*) * nalgs);
pqlr_kem_get_algs(kems, nalgs);
free(kems);
}
void use_new(void)
{
pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
// free resources
pqlr_kem_free(saber);
}
void use_generate_keys(void)
{
pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
const size_t sk_len = pqlr_kem_get_initiator_secret_length(saber);
const size_t pk_len = pqlr_kem_get_initiator_public_length(saber);
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
pqlr_kem_keygen(saber, pk, sk);
// free resources
pqlr_kem_free(saber);
free(pk);
free(sk);
}
void use_encap()
{
pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
const size_t pk_len = pqlr_kem_get_initiator_public_length(saber);
const size_t ct_len = pqlr_kem_get_ciphertext_length(saber);
const size_t sh_len = pqlr_kem_get_shared_secret_length(saber);
uint8_t* sh_key = (uint8_t*)calloc(sh_len, sizeof(uint8_t));
uint8_t* ct = (uint8_t*)calloc(ct_len, sizeof(uint8_t));
// get public key from somewhere
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
pqlr_kem_encap(saber, pk, ct, sh_key);
// free resources
pqlr_kem_free(saber);
free(pk);
free(ct);
free(sh_key);
}
void use_decap()
{
pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
const size_t pk_len = pqlr_kem_get_initiator_public_length(saber);
const size_t sk_len = pqlr_kem_get_initiator_secret_length(saber);
const size_t ct_len = pqlr_kem_get_ciphertext_length(saber);
const size_t sh_len = pqlr_kem_get_shared_secret_length(saber);
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
uint8_t* sh_key = (uint8_t*)calloc(sh_len, sizeof(uint8_t));
pqlr_kem_keygen(saber, pk, sk);
// get ciphertext from somewhere
uint8_t* ct = (uint8_t*)calloc(ct_len, sizeof(uint8_t));
pqlr_kem_decap(saber, sk, ct, sh_key);
// free resources
pqlr_kem_free(saber);
free(pk);
free(sk);
free(ct);
free(sh_key);
}
int main(void)
{
use_kem_get_algs();
use_new();
use_generate_keys();
use_encap();
use_decap();
}
struct pqlr_alg_st * pqlr_alg
PQLR algorithm instance handle.
Definition: alg.h:40
PQLR_API void pqlr_alg_free(pqlr_alg alg)
Frees pqlr_alg instance and all corresponding resources.
PQLR_API pqlr_alg pqlr_alg_new(const char *alg_str)
Creates pqlr_alg instance.
PQLR_API uint32_t pqlr_kem_get_ciphertext_length(const pqlr_kem kem)
Obtains ciphertext (request) length for the current pqlr_kem instance.
PQLR_API size_t pqlr_kem_num_algs(void)
Obtains the number of available PQLR KEM algorithms.
PQLR_API void pqlr_kem_free(pqlr_kem kem)
Frees pqlr_kem instance and all corresponding resources.
PQLR_API uint32_t pqlr_kem_get_initiator_secret_length(const pqlr_kem kem)
Obtains initiator's secret key length for the current pqlr_kem instance.
PQLR_API pqlr_kem pqlr_kem_new(const pqlr_alg alg)
Creates pqlr_kem instance initialized by alg.
struct pqlr_kem_st * pqlr_kem
PQLR KEM algorithm instance handle.
Definition: kem.h:53
PQLR_API size_t pqlr_kem_get_algs(const char **algs, size_t count)
Fills the provided buffer with names of available KEM algorithms.
PQLR_API uint32_t pqlr_kem_get_shared_secret_length(const pqlr_kem kem)
Obtains shared secret (key) length for the current pqlr_kem instance.
PQLR_API uint32_t pqlr_kem_get_initiator_public_length(const pqlr_kem kem)
Obtains initiator's public key length for the current pqlr_kem instance.
PQLR_API int pqlr_kem_encap(const pqlr_kem kem, const uint8_t *pk, uint8_t *ciphertext, uint8_t *session_key)
Second step of key distribution. Encapsulates key on the responder side.
PQLR_API int pqlr_kem_decap(const pqlr_kem kem, const uint8_t *sk, const uint8_t *ciphertext, uint8_t *session_key)
Last step of key distribution. Decapsulates key on the initiator side.
PQLR_API int pqlr_kem_keygen(const pqlr_kem kem, uint8_t *pk, uint8_t *sk)
Initial step of key distribution. Generates a key pair for key distribution initiator.

Typedef Documentation

◆ pqlr_kem

typedef struct pqlr_kem_st* pqlr_kem

PQLR KEM algorithm instance handle.

Function Documentation

◆ pqlr_kem_decap()

PQLR_API int pqlr_kem_decap ( const pqlr_kem  kem,
const uint8_t *  sk,
const uint8_t *  ciphertext,
uint8_t *  session_key 
)

Last step of key distribution. Decapsulates key on the initiator side.

Usage:

pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
const size_t pk_len = pqlr_kem_get_initiator_public_length(saber);
const size_t sk_len = pqlr_kem_get_initiator_secret_length(saber);
const size_t ct_len = pqlr_kem_get_ciphertext_length(saber);
const size_t sh_len = pqlr_kem_get_shared_secret_length(saber);
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
uint8_t* sh_key = (uint8_t*)calloc(sh_len, sizeof(uint8_t));
pqlr_kem_keygen(saber, pk, sk);
// get ciphertext from somewhere
uint8_t* ct = (uint8_t*)calloc(ct_len, sizeof(uint8_t));
pqlr_kem_decap(saber, sk, ct, sh_key);
Parameters
[in]kempqlr_kem algorithm context. If NULL, the fatal error occurs.
[in]skSecret key buffer ( pqlr_kem_keygen ). Must point to array of uint8_t with elements count at least pqlr_kem_get_initiator_secret_length. If NULL, the fatal error occurs.
[in]ciphertextEncoded request from the responder. Must point to array of uint8_t, with elements count at least pqlr_kem_get_ciphertext_length. If NULL, the fatal error occurs.
[out]session_keyDistributed key, equal to the key to be obtained on the responder side. Must point to array of uint8_t, with elements count at least pqlr_kem_get_shared_secret_length. If NULL, the fatal error occurs.
See also
pqlr_kem_new
pqlr_kem_keygen
pqlr_kem_key_encap
Returns
0 on success or non-zero value on failure

◆ pqlr_kem_duplicate()

PQLR_API pqlr_kem pqlr_kem_duplicate ( const pqlr_kem  kem)

duplicates the context of pqlr_kem algorithm

Parameters
[in]keminstance to duplicate
See also
pqlr_kem
Returns
new instance with duplicated context

◆ pqlr_kem_encap()

PQLR_API int pqlr_kem_encap ( const pqlr_kem  kem,
const uint8_t *  pk,
uint8_t *  ciphertext,
uint8_t *  session_key 
)

Second step of key distribution. Encapsulates key on the responder side.

Usage:

pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
const size_t pk_len = pqlr_kem_get_initiator_public_length(saber);
const size_t ct_len = pqlr_kem_get_ciphertext_length(saber);
const size_t sh_len = pqlr_kem_get_shared_secret_length(saber);
uint8_t* sh_key = (uint8_t*)calloc(sh_len, sizeof(uint8_t));
uint8_t* ct = (uint8_t*)calloc(ct_len, sizeof(uint8_t));
// get public key from somewhere
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
pqlr_kem_encap(saber, pk, ct, sh_key);
Parameters
[in]kempqlr_kem algorithm context. If NULL, the fatal error occurs.
[in]pkPublic key buffer ( pqlr_kem_keygen ). Must point to array of uint8_t with elements count at least pqlr_kem_get_initiator_public_length. If NULL, the fatal error occurs.
[out]ciphertextEncoded request from the responder. Must point to array of uint8_t, with elements count at least pqlr_kem_get_ciphertext_length. If NULL, the fatal error occurs.
[out]session_keyDistributed key, equal to the key to be obtained on the initiator side. Must point to array of uint8_t, with elements count at least pqlr_kem_get_shared_secret_length. If NULL, the fatal error occurs.
See also
pqlr_kem_new
pqlr_kem_keygen
pqlr_kem_get_initiator_public_length
pqlr_kem_get_ciphertext_length
pqlr_kem_get_shared_secret_length
pqlr_kem
Returns
0 on success or non-zero value on failure

◆ pqlr_kem_free()

PQLR_API void pqlr_kem_free ( pqlr_kem  kem)

Frees pqlr_kem instance and all corresponding resources.

Parameters
[in]keminstance to free
See also
pqlr_kem
pqlr_kem_new

◆ pqlr_kem_get_algs()

PQLR_API size_t pqlr_kem_get_algs ( const char **  algs,
size_t  count 
)

Fills the provided buffer with names of available KEM algorithms.

Usage:

size_t nalgs = pqlr_kem_num_algs();
const char** kems = malloc(sizeof(const char*) * nalgs);
pqlr_kem_get_algs(kems, nalgs);
Note
If the number of KEM algorithms is more than the array size, then it'll be truncated. Individual strings in the output array must not be freed.
Parameters
[out]algsArray of KEM names
[in]countArray size
Returns
number of algorithms in the output array.
See also
pqlr_alg
pqlr_alg_new
pqlr_kem_num_algs

◆ pqlr_kem_get_ciphertext_length()

PQLR_API uint32_t pqlr_kem_get_ciphertext_length ( const pqlr_kem  kem)

Obtains ciphertext (request) length for the current pqlr_kem instance.

Parameters
[in]keminitialized pqlr_kem instance
See also
pqlr_kem
pqlr_kem_new
Returns
ciphertext length

◆ pqlr_kem_get_initiator_public_length()

PQLR_API uint32_t pqlr_kem_get_initiator_public_length ( const pqlr_kem  kem)

Obtains initiator's public key length for the current pqlr_kem instance.

Parameters
[in]keminitialized pqlr_kem instance
See also
pqlr_kem
pqlr_kem_new
Returns
initiator's public key length

◆ pqlr_kem_get_initiator_secret_length()

PQLR_API uint32_t pqlr_kem_get_initiator_secret_length ( const pqlr_kem  kem)

Obtains initiator's secret key length for the current pqlr_kem instance.

Parameters
[in]keminitialized pqlr_kem instance
See also
pqlr_kem
pqlr_kem_new
Returns
initiator's secret key length

◆ pqlr_kem_get_shared_secret_length()

PQLR_API uint32_t pqlr_kem_get_shared_secret_length ( const pqlr_kem  kem)

Obtains shared secret (key) length for the current pqlr_kem instance.

Parameters
[in]keminitialized pqlr_kem instance
See also
pqlr_kem
pqlr_kem_new
Returns
shared secret length

◆ pqlr_kem_keygen()

PQLR_API int pqlr_kem_keygen ( const pqlr_kem  kem,
uint8_t *  pk,
uint8_t *  sk 
)

Initial step of key distribution. Generates a key pair for key distribution initiator.

Usage:

pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
const size_t sk_len = pqlr_kem_get_initiator_secret_length(saber);
const size_t pk_len = pqlr_kem_get_initiator_public_length(saber);
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
pqlr_kem_keygen(saber, pk, sk);
Note
Called on initiator side.
Parameters
[in]kempqlr_kem algorithm context. If NULL, the fatal error occurs.
[out]pkPublic key buffer. Must point to array of uint8_t with elements count at least pqlr_kem_get_initiator_public_length. If NULL, the fatal error occurs.
[out]skSecret key buffer. Must point to array of uint8_t with elements count at least pqlr_kem_get_initiator_secret_length. If NULL, the fatal error occurs.
See also
pqlr_kem_new
pqlr_kem_get_initiator_public_length
pqlr_kem_get_initiator_secret_length
pqlr_kem
Returns
0 on success or non-zero value on failure

◆ pqlr_kem_new()

PQLR_API pqlr_kem pqlr_kem_new ( const pqlr_alg  alg)

Creates pqlr_kem instance initialized by alg.

Usage:

pqlr_alg alg = pqlr_alg_new("saber");
pqlr_kem saber = pqlr_kem_new(alg);
Note
Called on both sides.
Parameters
[in]algInitialized PQLR KEM algorithm instance
See also
pqlr_alg_conf
pqlr_kem
pqlr_kem_free
Returns
new pqlr_kem instance or NULL if out of memory

◆ pqlr_kem_num_algs()

PQLR_API size_t pqlr_kem_num_algs ( void  )

Obtains the number of available PQLR KEM algorithms.

Returns
number of algorithms
See also
pqlr_kem_get_algs
pqlr_alg
pqlr_alg_new