PQLR
Postquantum Crypto Library by QAPP
SLH-DSA signature scheme

Typedefs

typedef struct slh_dsa_st * slh_dsa_t
 slh_dsa algorithm instance handle More...
 

Enumerations

enum  slh_dsa_parameterset_t {
  slh_dsa_parameterset_256s , slh_dsa_parameterset_256f , slh_dsa_parameterset_192s , slh_dsa_parameterset_192f ,
  slh_dsa_parameterset_128s , slh_dsa_parameterset_128f , slh_dsa_parameterset_last
}
 Parameter set. More...
 

Functions

PQLR_API slh_dsa_t slh_dsa_new (slh_dsa_parameterset_t parameterset)
 Creates new slh_dsa instance with selected parameter set. More...
 
PQLR_API void slh_dsa_free (slh_dsa_t slh_dsa)
 Frees slh_dsa instance and all corresponding resources. More...
 
PQLR_API slh_dsa_t slh_dsa_duplicate (const slh_dsa_t slh_dsa)
 Duplicates slh_dsa context. More...
 
PQLR_API pqlr_t slh_dsa_to_pqlr (slh_dsa_t slh_dsa)
 Gets pqlr instance linked to this slh_dsa instance. More...
 
PQLR_API size_t slh_dsa_get_signature_bytes_len (slh_dsa_t slh_dsa)
 Obtains signature buffer length in bytes for current slh_dsa instance. More...
 
PQLR_API size_t slh_dsa_get_public_key_bytes_len (slh_dsa_t slh_dsa)
 Obtains public key buffer length in bytes for current slh_dsa instance. More...
 
PQLR_API size_t slh_dsa_get_secret_key_bytes_len (slh_dsa_t slh_dsa)
 Obtains secret key buffer length in bytes for current slh_dsa instance. More...
 
PQLR_API void slh_dsa_generate_keys (const slh_dsa_t slh_dsa, uint8_t *result_sk, uint8_t *result_pk)
 Generates random secret key and public key for given context. More...
 
PQLR_API void slh_dsa_sign (const slh_dsa_t slh_dsa, const uint8_t *sk, const uint8_t *msg, size_t msg_len, uint8_t *result_sig, size_t *result_sig_len)
 Generates signature for given message according to context and secret key. The signature is non-deterministic, i.e. there are different results for the same message. More...
 
PQLR_API void slh_dsa_sign_ex (const slh_dsa_t slh_dsa, const uint8_t *sk, const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, size_t msg_len, uint8_t *result_sig, size_t *sig_len)
 Generates signature for given message according to context and secret key. The signature is non-deterministic, i.e. there are different results for the same message. More...
 
PQLR_API int slh_dsa_verify (const slh_dsa_t slh_dsa, const uint8_t *pk, const uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len)
 Verifies that given signature is the signature of given message. More...
 
PQLR_API int slh_dsa_verify_ex (const slh_dsa_t slh_dsa, const uint8_t *pk, const uint8_t *sig, size_t sig_len, const uint8_t *ctx, size_t ctx_len, const uint8_t *msg, size_t msg_len)
 Verifies that given signature is the signature of given message with additional context information. More...
 

Detailed Description

This module provides SLH-DSA algorithm implementation, which is a stateless hash-based signature scheme. The basic idea is to authenticate a huge number of few-time signature (FTS) key pairs using a so-called hypertree. FTS schemes are signature schemes that allow a key pair to produce a small number of signatures, e.g., in the order of ten for our parameter sets. For each new message, a (pseudo)random FTS key pair is chosen to sign the message. Signature consists of FTS signature and corresponding authentication information. The authentication information is roughly a hypertree signature, i.e. a signature using a certification tree of Merkle tree signatures.

General usage

At first, initialize algorithm's instance with parameters you want with slh_dsa_new(). After that, you can generate secret and public keys using slh_dsa_generate_keys(), then sign your message with slh_dsa_sign(), or verify message wasn't changed with slh_dsa_verify(). You are able to interact with this algorithm likewise pqlr_t instance(change error handler, source of entropy input, e.t.c) via slh_dsa_to_pqlr() call.

After the signature scheme is no more needed it's resources must freed by slh_dsa_free.

In order to use any SLH-DSA signature scheme functions, add following include:

Example code is listed below:

void use_new(void)
{
// free resources
slh_dsa_free(slh_dsa);
}
void use_generate_keys(void)
{
const size_t sk_len = slh_dsa_get_secret_key_bytes_len(slh_dsa);
const size_t pk_len = slh_dsa_get_public_key_bytes_len(slh_dsa);
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
slh_dsa_generate_keys(slh_dsa, sk, pk);
// free resources
free(pk);
free(sk);
slh_dsa_free(slh_dsa);
}
void use_sign(void)
{
const size_t sk_len = slh_dsa_get_secret_key_bytes_len(slh_dsa);
// get secret key from somewhere
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
size_t sig_len = slh_dsa_get_signature_bytes_len(slh_dsa);
uint8_t* sig = (uint8_t*)calloc(sig_len, sizeof(uint8_t));
unsigned char msg[] = "test";
slh_dsa_sign(slh_dsa, sk, msg, sizeof(msg), sig, &sig_len);
// free resources
free(sig);
free(sk);
slh_dsa_free(slh_dsa);
}
void use_verify(void)
{
const size_t pk_len = slh_dsa_get_public_key_bytes_len(slh_dsa);
size_t sig_len = slh_dsa_get_signature_bytes_len(slh_dsa);
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
uint8_t* sig = (uint8_t*)calloc(sig_len, sizeof(uint8_t));
unsigned char msg[] = "test";
int res = slh_dsa_verify(slh_dsa, pk, sig, sig_len, msg, sizeof(msg));
// free resources
free(sig);
free(pk);
slh_dsa_free(slh_dsa);
}
int main(void)
{
use_new();
use_generate_keys();
use_sign();
use_verify();
}
PQLR_API void slh_dsa_generate_keys(const slh_dsa_t slh_dsa, uint8_t *result_sk, uint8_t *result_pk)
Generates random secret key and public key for given context.
PQLR_API void slh_dsa_free(slh_dsa_t slh_dsa)
Frees slh_dsa instance and all corresponding resources.
PQLR_API void slh_dsa_sign(const slh_dsa_t slh_dsa, const uint8_t *sk, const uint8_t *msg, size_t msg_len, uint8_t *result_sig, size_t *result_sig_len)
Generates signature for given message according to context and secret key. The signature is non-deter...
PQLR_API int slh_dsa_verify(const slh_dsa_t slh_dsa, const uint8_t *pk, const uint8_t *sig, size_t sig_len, const uint8_t *msg, size_t msg_len)
Verifies that given signature is the signature of given message.
PQLR_API size_t slh_dsa_get_public_key_bytes_len(slh_dsa_t slh_dsa)
Obtains public key buffer length in bytes for current slh_dsa instance.
struct slh_dsa_st * slh_dsa_t
slh_dsa algorithm instance handle
Definition: slh_dsa.h:61
PQLR_API slh_dsa_t slh_dsa_new(slh_dsa_parameterset_t parameterset)
Creates new slh_dsa instance with selected parameter set.
PQLR_API size_t slh_dsa_get_signature_bytes_len(slh_dsa_t slh_dsa)
Obtains signature buffer length in bytes for current slh_dsa instance.
PQLR_API size_t slh_dsa_get_secret_key_bytes_len(slh_dsa_t slh_dsa)
Obtains secret key buffer length in bytes for current slh_dsa instance.
@ slh_dsa_parameterset_256s
Slow 256 bit preset.
Definition: params.h:43
@ slh_dsa_parameterset_128f
Fast 128 bit preset.
Definition: params.h:48

Typedef Documentation

◆ slh_dsa_t

typedef struct slh_dsa_st* slh_dsa_t

slh_dsa algorithm instance handle

Note
pqlr_t instance linked to this handle can be obtained
See also
slh_dsa_to_pqlr

Enumeration Type Documentation

◆ slh_dsa_parameterset_t

Parameter set.

SLH-DSA can be parametrized with one of predefined parameter sets. Based on parameter set, following algorithm properties are changed:

  • security level (in bits)
  • private key size (in bytes)
  • public key size (in bytes)
  • signature size (in bytes)
  • hash count (number of hash operations performed during message signing)

Property values summarized in table below.

Paramset Security level Private key size Public key size Signature size Hash count
128s 133 64 32 8 080 2 205 679
128f 128 64 32 16 976 141 551
192s 196 96 48 17 064 4 532 203
192f 194 96 48 35 664 178 234
256s 255 128 64 29 792 3 418 083
256f 254 128 64 49 216 402 466

Computation speed will differ depending on chosen parameter sets due to different count of internal hash operations performed.

Enumerator
slh_dsa_parameterset_256s 

Slow 256 bit preset.

slh_dsa_parameterset_256f 

Fast 256 bit preset.

slh_dsa_parameterset_192s 

Slow 192 bit preset.

slh_dsa_parameterset_192f 

Fast 192 bit preset.

slh_dsa_parameterset_128s 

Slow 128 bit preset.

slh_dsa_parameterset_128f 

Fast 128 bit preset.

slh_dsa_parameterset_last 

Function Documentation

◆ slh_dsa_duplicate()

PQLR_API slh_dsa_t slh_dsa_duplicate ( const slh_dsa_t  slh_dsa)

Duplicates slh_dsa context.

Parameters
slh_dsacontext to duplicate
Returns
copy of slh_dsa
See also
sphinx_plut_t
sphinx_plus_new

◆ slh_dsa_free()

PQLR_API void slh_dsa_free ( slh_dsa_t  slh_dsa)

Frees slh_dsa instance and all corresponding resources.

Parameters
slh_dsainstance to free
See also
slh_dsa_t
slh_dsa_new

◆ slh_dsa_generate_keys()

PQLR_API void slh_dsa_generate_keys ( const slh_dsa_t  slh_dsa,
uint8_t *  result_sk,
uint8_t *  result_pk 
)

Generates random secret key and public key for given context.

Usage:

const size_t sk_len = slh_dsa_get_secret_key_bytes_len(slh_dsa);
const size_t pk_len = slh_dsa_get_public_key_bytes_len(slh_dsa);
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
slh_dsa_generate_keys(slh_dsa, sk, pk);
Parameters
slh_dsaInstance of slh_dsa created with slh_dsa_new(). If NULL, the fatal error occurs.
[out]result_skContiguous array to receive secret key, of size slh_dsa_get_secret_key_bytes_len. If NULL, the fatal error occurs.
[out]result_pkContiguous array to receive public key, of size slh_dsa_get_public_key_bytes_len. If NULL, the fatal error occurs.
See also
slh_dsa_get_secret_key_bytes_len
slh_dsa_get_public_key_bytes_len

◆ slh_dsa_get_public_key_bytes_len()

PQLR_API size_t slh_dsa_get_public_key_bytes_len ( slh_dsa_t  slh_dsa)

Obtains public key buffer length in bytes for current slh_dsa instance.

Parameters
slh_dsainitialized slh_dsa instance
See also
slh_dsa_t
slh_dsa_new
Returns
public key buffer length in bytes

◆ slh_dsa_get_secret_key_bytes_len()

PQLR_API size_t slh_dsa_get_secret_key_bytes_len ( slh_dsa_t  slh_dsa)

Obtains secret key buffer length in bytes for current slh_dsa instance.

Parameters
slh_dsainitialized slh_dsa instance
See also
slh_dsa_t
slh_dsa_new
Returns
secret key buffer length in bytes

◆ slh_dsa_get_signature_bytes_len()

PQLR_API size_t slh_dsa_get_signature_bytes_len ( slh_dsa_t  slh_dsa)

Obtains signature buffer length in bytes for current slh_dsa instance.

Parameters
slh_dsainitialized slh_dsa instance
See also
slh_dsa_t
slh_dsa_new
Returns
signature buffer length in bytes

◆ slh_dsa_new()

PQLR_API slh_dsa_t slh_dsa_new ( slh_dsa_parameterset_t  parameterset)

Creates new slh_dsa instance with selected parameter set.

Usage:

Parameters
parametersetParameter set (see slh_dsa_parameterset_t for available options)
Returns
initialized slh_dsa instance or NULL if out of memory

◆ slh_dsa_sign()

PQLR_API void slh_dsa_sign ( const slh_dsa_t  slh_dsa,
const uint8_t *  sk,
const uint8_t *  msg,
size_t  msg_len,
uint8_t *  result_sig,
size_t *  result_sig_len 
)

Generates signature for given message according to context and secret key. The signature is non-deterministic, i.e. there are different results for the same message.

Usage:

const size_t sk_len = slh_dsa_get_secret_key_bytes_len(slh_dsa);
// get secret key from somewhere
uint8_t* sk = (uint8_t*)calloc(sk_len, sizeof(uint8_t));
size_t sig_len = slh_dsa_get_signature_bytes_len(slh_dsa);
uint8_t* sig = (uint8_t*)calloc(sig_len, sizeof(uint8_t));
unsigned char msg[] = "test";
slh_dsa_sign(slh_dsa, sk, msg, sizeof(msg), sig, &sig_len);
Parameters
slh_dsaInstance of slh_dsa created with slh_dsa_new(). If NULL, the fatal error occurs.
skSecret key, the contiguous array of size slh_dsa_get_secret_key_bytes_len. If NULL, the fatal error occurs.
msgMessage to generate signature of, the contiguous array. If NULL, the fatal error occurs.
msg_lenThe length of a message in bytes. If 0, the fatal error occurs.
[out]result_sigContiguous array to receive signature, of size slh_dsa_get_signature_bytes_len. If NULL, the fatal error occurs.
[out]result_sig_lenThe length of a signature in bytes. If NULL, the fatal error occurs.
See also
slh_dsa_get_signature_bytes_len
slh_dsa_get_secret_key_bytes_len

◆ slh_dsa_sign_ex()

PQLR_API void slh_dsa_sign_ex ( const slh_dsa_t  slh_dsa,
const uint8_t *  sk,
const uint8_t *  ctx,
size_t  ctx_len,
const uint8_t *  msg,
size_t  msg_len,
uint8_t *  result_sig,
size_t *  sig_len 
)

Generates signature for given message according to context and secret key. The signature is non-deterministic, i.e. there are different results for the same message.

Parameters
slh_dsaInstance of slh_dsa created with slh_dsa_new(). If NULL, the fatal error occurs.
skSecret key, the contiguous array of size slh_dsa_get_secret_key_bytes_len. If NULL, the fatal error occurs.
ctxContext string to be used when computing the signature
ctx_lenContext string length
msgMessage to generate signature of, the contiguous array. If NULL, the fatal error occurs.
msg_lenThe length of a message in bytes. If 0, the fatal error occurs.
[out]result_sigContiguous array to receive signature, of size slh_dsa_get_signature_bytes_len. If NULL, the fatal error occurs.
[out]sig_lenThe length of a signature in bytes. If NULL, the fatal error occurs.
See also
slh_dsa_get_signature_bytes_len
slh_dsa_get_secret_key_bytes_len

◆ slh_dsa_to_pqlr()

PQLR_API pqlr_t slh_dsa_to_pqlr ( slh_dsa_t  slh_dsa)

Gets pqlr instance linked to this slh_dsa instance.

Parameters
slh_dsainitialized slh_dsa instance
Note
this call leaves slh_dsa instance intact
the returned pqlr instance will be released on call to slh_dsa_free()
See also
slh_dsa_t
pqlr_t
slh_dsa_free
Returns
operable pqlr instance or NULL if slh_dsa is NULL

◆ slh_dsa_verify()

PQLR_API int slh_dsa_verify ( const slh_dsa_t  slh_dsa,
const uint8_t *  pk,
const uint8_t *  sig,
size_t  sig_len,
const uint8_t *  msg,
size_t  msg_len 
)

Verifies that given signature is the signature of given message.

Usage:

const size_t pk_len = slh_dsa_get_public_key_bytes_len(slh_dsa);
size_t sig_len = slh_dsa_get_signature_bytes_len(slh_dsa);
uint8_t* pk = (uint8_t*)calloc(pk_len, sizeof(uint8_t));
uint8_t* sig = (uint8_t*)calloc(sig_len, sizeof(uint8_t));
unsigned char msg[] = "test";
int res = slh_dsa_verify(slh_dsa, pk, sig, sig_len, msg, sizeof(msg));
Parameters
slh_dsaContext, initialized with slh_dsa_new(). If NULL, the fatal error occurs.
pkPublic key, the contiguous array of size slh_dsa_get_public_key_bytes_len. If NULL, the fatal error occurs.
sigSignature, the contiguous array of size ‘slh_dsa_get_signature_bytes_len’. If NULL, the fatal error occurs.
sig_lenThe length of a signature in bytes.
msgMessage to verify signature of, the contiguous array. If NULL, the fatal error occurs.
msg_lenThe length of a message in bytes. If 0, the fatal error occurs.
Returns
0 if given signature is the signature of given message, otherwise non-zero value.
See also
slh_dsa_get_signature_bytes_len
slh_dsa_get_public_key_bytes_len

◆ slh_dsa_verify_ex()

PQLR_API int slh_dsa_verify_ex ( const slh_dsa_t  slh_dsa,
const uint8_t *  pk,
const uint8_t *  sig,
size_t  sig_len,
const uint8_t *  ctx,
size_t  ctx_len,
const uint8_t *  msg,
size_t  msg_len 
)

Verifies that given signature is the signature of given message with additional context information.

Parameters
slh_dsaContext, initialized with slh_dsa_new(). If NULL, the fatal error occurs.
pkPublic key, the contiguous array of size slh_dsa_get_public_key_bytes_len. If NULL, the fatal error occurs.
sigSignature, the contiguous array of size slh_dsa_get_signature_bytes_len. If NULL, the fatal error occurs.
sig_lenThe length of a signature in bytes.
ctxContext information, the contiguous array. If NULL, the fatal error occurs.
ctx_lenThe length of context information in bytes.
msgMessage to verify signature of, the contiguous array. If NULL, the fatal error occurs.
msg_lenThe length of a message in bytes. If 0, the fatal error occurs.
Returns
0 if given signature is the signature of given message, otherwise non-zero value.
See also
slh_dsa_get_signature_bytes_len
slh_dsa_get_public_key_bytes_len
slh_dsa_sign_ex