ISARA Radiate Security Solution Suite Toolkit Edition Version 1.5

Quantum-safe cryptographic primitives and algorithms.

iqr_xmss.h File Reference

ISARA Radiate Security Solution Suite's eXtended Merkle Signature Scheme. More...

Typedefs

typedef struct iqr_XMSSPrivateKeyState_struct iqr_XMSSPrivateKeyState
 
typedef struct iqr_XMSSParams_struct iqr_XMSSParams
 
typedef struct iqr_XMSSPublicKey_struct iqr_XMSSPublicKey
 
typedef struct iqr_XMSSPrivateKey_struct iqr_XMSSPrivateKey
 
typedef struct iqr_XMSSTreeStrategy_struct iqr_XMSSTreeStrategy
 

Enumerations

enum  iqr_XMSSHeight {
  IQR_XMSS_HEIGHT_10 = 0,
  IQR_XMSS_HEIGHT_16 = 1,
  IQR_XMSS_HEIGHT_20 = 2
}
 

Functions

IQR_API iqr_retval iqr_XMSSCreateParams (const iqr_Context *ctx, const iqr_XMSSTreeStrategy *strategy, iqr_XMSSHeight h, iqr_XMSSParams **params)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyParams (iqr_XMSSParams **params)
 
IQR_API iqr_retval iqr_XMSSCreateKeyPair (const iqr_XMSSParams *params, const iqr_RNG *rng, iqr_XMSSPublicKey **public_key, iqr_XMSSPrivateKey **private_key, iqr_XMSSPrivateKeyState **state)
 
IQR_API iqr_retval iqr_XMSSImportPrivateKey (const iqr_XMSSParams *params, const uint8_t *buf, size_t buf_size, iqr_XMSSPrivateKey **private_key)
 
IQR_API iqr_retval iqr_XMSSExportPrivateKey (const iqr_XMSSPrivateKey *private_key, uint8_t *buf, size_t buf_size)
 
IQR_API iqr_retval iqr_XMSSImportPublicKey (const iqr_XMSSParams *params, const uint8_t *buf, size_t buf_size, iqr_XMSSPublicKey **public_key)
 
IQR_API iqr_retval iqr_XMSSExportPublicKey (const iqr_XMSSPublicKey *public_key, uint8_t *buf, size_t buf_size)
 
IQR_API iqr_retval iqr_XMSSImportState (const iqr_XMSSParams *params, const uint8_t *buf, size_t buf_size, iqr_XMSSPrivateKeyState **state)
 
IQR_API iqr_retval iqr_XMSSExportState (const iqr_XMSSPrivateKeyState *state, uint8_t *buf, size_t buf_size)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyPrivateKey (iqr_XMSSPrivateKey **private_key)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyPublicKey (iqr_XMSSPublicKey **public_key)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyState (iqr_XMSSPrivateKeyState **state)
 
IQR_API iqr_retval iqr_XMSSDetachState (const iqr_XMSSPrivateKey *private_key, iqr_XMSSPrivateKeyState *state, uint32_t num_sigs, iqr_XMSSPrivateKeyState **detached_state)
 
IQR_API iqr_retval iqr_XMSSGetPrivateKeySize (const iqr_XMSSPrivateKey *private_key, size_t *private_key_size)
 
IQR_API iqr_retval iqr_XMSSGetPublicKeySize (const iqr_XMSSPublicKey *public_key, size_t *public_key_size)
 
IQR_API iqr_retval iqr_XMSSGetStateSize (const iqr_XMSSPrivateKeyState *state, size_t *state_size)
 
IQR_API iqr_retval iqr_XMSSGetSignatureSize (const iqr_XMSSParams *params, size_t *sig_size)
 
IQR_API iqr_retval iqr_XMSSGetSignatureCount (const iqr_XMSSPrivateKeyState *state, uint32_t *max_sigs, uint32_t *remaining_sigs)
 
IQR_API iqr_retval iqr_XMSSSign (const iqr_XMSSPrivateKey *private_key, const iqr_RNG *rng, const uint8_t *message, size_t message_size, iqr_XMSSPrivateKeyState *state, uint8_t *sig, size_t sig_size)
 
IQR_API iqr_retval iqr_XMSSVerify (const iqr_XMSSPublicKey *public_key, const uint8_t *message, size_t message_size, const uint8_t *sig, size_t sig_size)
 

Variables

IQR_EXTERN const iqr_XMSSTreeStrategy IQR_XMSS_BDS_STRATEGY
 
IQR_EXTERN const iqr_XMSSTreeStrategy IQR_XMSS_FULL_STRATEGY
 
IQR_EXTERN const iqr_XMSSTreeStrategy IQR_XMSS_VERIFY_ONLY_STRATEGY
 

Typedef Documentation

◆ iqr_XMSSParams

typedef struct iqr_XMSSParams_struct iqr_XMSSParams

The XMSS algorithm's domain parameters.

◆ iqr_XMSSPrivateKey

typedef struct iqr_XMSSPrivateKey_struct iqr_XMSSPrivateKey

The XMSS private key.

◆ iqr_XMSSPrivateKeyState

typedef struct iqr_XMSSPrivateKeyState_struct iqr_XMSSPrivateKeyState

The XMSS private state.

◆ iqr_XMSSPublicKey

typedef struct iqr_XMSSPublicKey_struct iqr_XMSSPublicKey

The XMSS public key.

◆ iqr_XMSSTreeStrategy

typedef struct iqr_XMSSTreeStrategy_struct iqr_XMSSTreeStrategy

The XMSS tree strategy.

Enumeration Type Documentation

◆ iqr_XMSSHeight

Supported XMSS tree heights.

The XMSS tree height, as documented in section 5.3 of the IETF draft. The height dictates the number of one-time signatures available (2height).

Enumerator
IQR_XMSS_HEIGHT_10 

Provide 1024 (210) one-time signatures.

IQR_XMSS_HEIGHT_16 

Provide 65,536 (216) one-time signatures.

IQR_XMSS_HEIGHT_20 

Provide 1,048,576 (220) one-time signatures.

Function Documentation

◆ iqr_XMSSCreateKeyPair()

IQR_API iqr_retval iqr_XMSSCreateKeyPair ( const iqr_XMSSParams params,
const iqr_RNG rng,
iqr_XMSSPublicKey **  public_key,
iqr_XMSSPrivateKey **  private_key,
iqr_XMSSPrivateKeyState **  state 
)

Generate an XMSS private/public key pair.

This can take a significant amount of time, especially when creating a height 20 tree (using IQR_XMSS_HEIGHT_20).

The iqr_XMSSCreateKeyPair() function calls the watchdog callback (see iqr_watchdog.h).

Note
You must register a SHA2-256 implementation by calling iqr_HashRegisterCallbacks() before using the XMSS API.

The rng must be initialized before being passed to iqr_XMSSCreateKeyPair().

*public_key, *private_key, and state must be set to NULL before calling iqr_XMSSCreateKeyPair().

Parameters
[in]paramsThe key parameters to use.
[in]rngA seeded random number generator.
[out]public_keyThe resulting iqr_XMSSPublicKey object.
[out]private_keyThe resulting iqr_XMSSPrivateKey object.
[out]stateThe resulting iqr_XMSSPrivateKeyState object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSCreateParams()

IQR_API iqr_retval iqr_XMSSCreateParams ( const iqr_Context ctx,
const iqr_XMSSTreeStrategy strategy,
iqr_XMSSHeight  h,
iqr_XMSSParams **  params 
)

Create an XMSS Parameters object that encapsulates domain parameters.

It's up to the user to manage domain parameters; the parameter data is not exposed in stored keys or signatures.

Note
You must register a SHA2-256 implementation by calling iqr_HashRegisterCallbacks() before using the XMSS API.

*params must be set to NULL before calling iqr_XMSSCreateParams().

Parameters
[in]ctxA Context object.
[in]strategyThe tree strategy.
[in]hThe iqr_XMSSHeight.
[out]paramsThe iqr_XMSSParams output.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSDestroyParams()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyParams ( iqr_XMSSParams **  params)

Clear and deallocate an XMSS key parameters object.

params will be set to NULL before returning.

All internal iqr_XMSSParams buffers are cleared and deallocated during the call to iqr_XMSSDestroyParams(). The iqr_XMSSParams object does not store any cryptographic material.

Parameters
[in,out]paramsThe iqr_XMSSParams instance to destroy.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSDestroyPrivateKey()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyPrivateKey ( iqr_XMSSPrivateKey **  private_key)

Clear and deallocate an XMSS private key.

*private_key will be set to NULL prior to returning.

The private key's data is cleared before its internal buffers are deallocated.

Parameters
[in,out]private_keyThe iqr_XMSSPrivateKey object to destroy.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSDestroyPublicKey()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyPublicKey ( iqr_XMSSPublicKey **  public_key)

Clear and deallocate an XMSS public key.

*public_key will be set to NULL prior to returning.

Parameters
[in,out]public_keyThe iqr_XMSSPublicKey object to destroy.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSDestroyState()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_XMSSDestroyState ( iqr_XMSSPrivateKeyState **  state)

Clear and deallocate an XMSS state.

*state will be set to NULL prior to returning.

Parameters
[in,out]stateThe state object to destroy.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSDetachState()

IQR_API iqr_retval iqr_XMSSDetachState ( const iqr_XMSSPrivateKey private_key,
iqr_XMSSPrivateKeyState state,
uint32_t  num_sigs,
iqr_XMSSPrivateKeyState **  detached_state 
)

Detaches a subset of signatures from state into a new state object.

This function can be used to split a state into two distinct, non-overlapping state objects. This operation effectively "reserves" a number of signatures from state and places them into a new distinct object, detached_state. Both state objects must be used with the same private key to generate signatures.

This operation is useful for disaster recovery, whereby a small section of the state is detached and used for signing while the rest of the state is persisted in non-volatile memory. Or, this feature can be used to aid in the distribution of a state and key pair to multiple machines, where each machine is given a distinct state.

The detached_state will have a reduced number of maximum signatures once this function returns. Use iqr_XMSSGetSignatureCount() to obtain the number of available signatures. Use iqr_XMSSGetStateSize() to obtain the state sizes prior to exporting.

In the unlikely case that an error occurs while state is being updated, the state will become unusable. This function and any subsequent function calls will return IQR_ESTATECORRUPTED.

Parameters
[in]private_keyThe private key.
[in,out]stateThe original state to be split.
[in]num_sigsThe number of signatures to split off.
[out]detached_stateA new state object containing num_sigs signatures.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSExportPrivateKey()

IQR_API iqr_retval iqr_XMSSExportPrivateKey ( const iqr_XMSSPrivateKey private_key,
uint8_t *  buf,
size_t  buf_size 
)

Export the XMSS private key's data into a buffer.

Be sure to safely wipe and discard buf when you're done using it.

Parameters
[in]private_keyThe private key object.
[out]bufThe destination buffer.
[in]buf_sizeThe size of buf in bytes. Must be exactly the size returned by iqr_XMSSGetPrivateKeySize().
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSExportPublicKey()

IQR_API iqr_retval iqr_XMSSExportPublicKey ( const iqr_XMSSPublicKey public_key,
uint8_t *  buf,
size_t  buf_size 
)

Export the XMSS public key's data into a buffer.

Parameters
[in]public_keyThe public key object.
[out]bufThe destination buffer.
[in]buf_sizeThe size of buf in bytes. Must be exactly the size returned by iqr_XMSSGetPublicKeySize().
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSExportState()

IQR_API iqr_retval iqr_XMSSExportState ( const iqr_XMSSPrivateKeyState state,
uint8_t *  buf,
size_t  buf_size 
)

Export the XMSS state's data into a buffer.

Parameters
[in]stateThe state object.
[out]bufThe destination buffer.
[in]buf_sizeThe size of buf in bytes. Must be exactly the size returned by iqr_XMSSGetStateSize().
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSGetPrivateKeySize()

IQR_API iqr_retval iqr_XMSSGetPrivateKeySize ( const iqr_XMSSPrivateKey private_key,
size_t *  private_key_size 
)

Retrieves the size of the XMSS private key, in bytes.

Parameters
[in]private_keyThe private key.
[out]private_key_sizeThe size of the private key in bytes.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSGetPublicKeySize()

IQR_API iqr_retval iqr_XMSSGetPublicKeySize ( const iqr_XMSSPublicKey public_key,
size_t *  public_key_size 
)

Retrieve the size of the XMSS public key, in bytes.

Parameters
[in]public_keyThe public key.
[out]public_key_sizeThe size of the public key in bytes.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSGetSignatureCount()

IQR_API iqr_retval iqr_XMSSGetSignatureCount ( const iqr_XMSSPrivateKeyState state,
uint32_t *  max_sigs,
uint32_t *  remaining_sigs 
)

Get the number of signatures available with the given state.

The total number of signatures that can be generated is based on the height of the tree (governed by the iqr_XMSSHeight domain parameter). The number of remaining signatures depends on how many iqr_XMSSSign() operations have been performed.

Parameters
[in]stateThe state.
[out]max_sigsThe total number of signatures.
[out]remaining_sigsThe remaining number of signatures.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSGetSignatureSize()

IQR_API iqr_retval iqr_XMSSGetSignatureSize ( const iqr_XMSSParams params,
size_t *  sig_size 
)

Get the size of the signature.

Parameters
[in]paramsXMSS domain parameters.
[out]sig_sizeThe size of the XMSS signature for the given private key, in bytes.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSGetStateSize()

IQR_API iqr_retval iqr_XMSSGetStateSize ( const iqr_XMSSPrivateKeyState state,
size_t *  state_size 
)

Get the size of the XMSS state, in bytes.

Parameters
[in]stateThe state object.
[out]state_sizeThe size of the state in bytes.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSImportPrivateKey()

IQR_API iqr_retval iqr_XMSSImportPrivateKey ( const iqr_XMSSParams params,
const uint8_t *  buf,
size_t  buf_size,
iqr_XMSSPrivateKey **  private_key 
)

Import an XMSS private key object from a buffer.

The value of buf_size must be exactly the size given by iqr_XMSSGetPrivateKeySize().

Note
You must register a SHA2-256 implementation by calling iqr_HashRegisterCallbacks() before using the XMSS API.

*private_key must be set to NULL before calling iqr_XMSSImportPrivateKey(). Be sure to safely clear and discard buf after calling this function.

Parameters
[in]paramsXMSS parameters. Must be the same as when the keys were created.
[in]bufA buffer that contains a private key.
[in]buf_sizeThe size of buf in bytes. Must be exactly the size returned by iqr_XMSSGetPrivateKeySize().
[out]private_keyThe resulting iqr_XMSSPrivateKey object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSImportPublicKey()

IQR_API iqr_retval iqr_XMSSImportPublicKey ( const iqr_XMSSParams params,
const uint8_t *  buf,
size_t  buf_size,
iqr_XMSSPublicKey **  public_key 
)

Import an XMSS public key object from a buffer.

Note
You must register a SHA2-256 implementation by calling iqr_HashRegisterCallbacks() before using the XMSS API.

*public_key must be set to NULL before calling iqr_XMSSImportPublicKey().

Parameters
[in]paramsXMSS parameters. Must be the same as when the keys were created.
[in]bufA buffer containing the public key.
[in]buf_sizeThe size of buf in bytes. Must be exactly the size returned by iqr_XMSSGetPublicKeySize().
[out]public_keyThe resulting iqr_XMSSPublickey object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSImportState()

IQR_API iqr_retval iqr_XMSSImportState ( const iqr_XMSSParams params,
const uint8_t *  buf,
size_t  buf_size,
iqr_XMSSPrivateKeyState **  state 
)

Import an XMSS State object from a buffer.

The value of buf_size must be exactly the size given by iqr_XMSSGetStateSize().

*state must be set to NULL before calling iqr_XMSSImportState().

Parameters
[in]paramsXMSS parameters. Must be the same as when the keys were created.
[in]bufA buffer that contains a state.
[in]buf_sizeThe size of buf in bytes. Must be exactly the size returned by iqr_XMSSGetStateSize().
[out]stateThe resulting iqr_XMSSPrivateKeyState object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSSign()

IQR_API iqr_retval iqr_XMSSSign ( const iqr_XMSSPrivateKey private_key,
const iqr_RNG rng,
const uint8_t *  message,
size_t  message_size,
iqr_XMSSPrivateKeyState state,
uint8_t *  sig,
size_t  sig_size 
)

Sign a message using an XMSS private key.

As signatures are generated, the state can run out of signing keys. In that case, IQR_EKEYDEPLETED is returned and the key can no longer be used for signing. Use iqr_XMSSGetSignatureCount() to check to total number of signatures and the number of signatures remaining.

Each time this function is called, the state is advanced to the next usable state. You must store this new state in non-volatile memory prior to releasing the signature. Alternatively, use iqr_XMSSDetachState() to work with smaller states that can be lost without catastrophe. For more details, refer to the Developer's Guide (online: Toolkit edition, or Signature edition).

In the unlikely case that an error occurs while state is being updated, the state will become unusable. This function and any subsequent function calls will return IQR_ESTATECORRUPTED.

Warning
Restarting from a previous state makes XMSS insecure.

If the message is a digest of a hash function it must be 48 bytes or longer to be quantum-safe.

Note
You must register a SHA2-256 implementation by calling iqr_HashRegisterCallbacks() before using the XMSS API.

The rng must be initialized before being passed to iqr_XMSSSign().

All internal buffers are cleared and deallocated before the call to iqr_XMSSSign() returns.

Parameters
[in]private_keyThe private key.
[in]rngA seeded random number generator.
[in]messageThe message to be signed.
[in]message_sizeThe size of message in bytes.
[in,out]stateThe state object.
[out]sigThe buffer receiving the resulting signature.
[in]sig_sizeThe size of sig in bytes. Must be exactly the size returned by iqr_XMSSGetSignatureSize().
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

◆ iqr_XMSSVerify()

IQR_API iqr_retval iqr_XMSSVerify ( const iqr_XMSSPublicKey public_key,
const uint8_t *  message,
size_t  message_size,
const uint8_t *  sig,
size_t  sig_size 
)

Verify the signature of a message using an XMSS public key.

Note
If the message is a digest of a hash function it should be 48 bytes or longer to be quantum-safe.
You must register a SHA2-256 implementation by calling iqr_HashRegisterCallbacks() before using the XMSS API.

All internal buffers are cleared and deallocated before the call to iqr_XMSSVerify() returns.

Parameters
[in]public_keyThe public key.
[in]messageThe message to verify.
[in]message_sizeThe size of message in bytes.
[in]sigThe signature to verify.
[in]sig_sizeThe size of sig in bytes. Must be exactly the size returned by iqr_XMSSGetSignatureSize().
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

Variable Documentation

◆ IQR_XMSS_BDS_STRATEGY

IQR_EXTERN const iqr_XMSSTreeStrategy IQR_XMSS_BDS_STRATEGY

Tree strategies offer a trade-off between CPU utilization and memory usage during signing. Choosing the correct strategy is highly dependent on the hardware restrictions of the target platform.

Please see the Developer's Guide (online: Toolkit edition, or Signature edition) for state size requirements. Implements the BDS algorithm as proposed in the Merkle Tree Traversal Revisited Whitepaper. This strategy features minimal memory requirements at the cost of recomputing parts of the Merkle tree. This option is ideal for memory constrained devices with a fast CPU to handle recomputation. This is an excellent choice for embedded platforms, such as Hardware Security Modules.

◆ IQR_XMSS_FULL_STRATEGY

IQR_EXTERN const iqr_XMSSTreeStrategy IQR_XMSS_FULL_STRATEGY

Implements a full Merkle tree in memory. This strategy offers the least CPU utilization at the cost of using memory. This option is ideal for servers with large amounts of memory that need to generate signatures frequently. For larger tree heights, this strategy requires up to 2GB of memory to store the state.

◆ IQR_XMSS_VERIFY_ONLY_STRATEGY

IQR_EXTERN const iqr_XMSSTreeStrategy IQR_XMSS_VERIFY_ONLY_STRATEGY

This strategy is only used to verify signatures; it cannot be used to create or import private keys nor can it be used to create signatures. This option is ideal for a client that only needs to verify signatures.

Detailed Description

ISARA Radiate Security Solution Suite's eXtended Merkle Signature Scheme.

XMSS is defined by the RFC: XMSS: eXtended Merkle Signature Scheme by Huelsing et al.

This header contains the functions and parameters necessary to create and verify an XMSS signature. The two main functions are iqr_XMSSSign() and iqr_XMSSVerify(). The rest of the functions let you create and manipulate XMSS keys.

This scheme has some fundamental differences from traditional signature schemes such as RSA or ECDSA. In particular, you'll need to manage the state used by iqr_XMSSSign() carefully. For more details, refer to the Developer's Guide (online: Toolkit edition, or Signature edition).

Note
As specified above, the state is managed by the user. This differs from the IETF specification, where the state is stored and updated within the private key as an index.
License
The code and other content set out herein is not in the public domain, is considered a trade secret and is confidential to ISARA Corporation. Use, reproduction or distribution, in whole or in part, of such code or other content is strictly prohibited except by express written permission of ISARA Corporation. Please contact ISARA Corporation at info@.nosp@m.isar.nosp@m.a.com for more information.