ISARA Quantum Resistant Toolkit  Version 1.1
Quantum resistant cryptographic primitives and algorithms.
iqr_lms.h File Reference

Macros

#define IQR_LMS_PRIVATE_KEY_IDENTIFIER_SIZE   31
 

Typedefs

typedef struct iqr_LMSParams_struct iqr_LMSParams
 
typedef struct iqr_LMSPublicKey_struct iqr_LMSPublicKey
 
typedef struct iqr_LMSPrivateKey_struct iqr_LMSPrivateKey
 

Enumerations

enum  iqr_LMSWinternitz {
  IQR_LMS_WINTERNITZ_1 = 0,
  IQR_LMS_WINTERNITZ_2 = 1,
  IQR_LMS_WINTERNITZ_4 = 2,
  IQR_LMS_WINTERNITZ_8 = 3
}
 
enum  iqr_LMSHeight {
  IQR_LMS_HEIGHT_20 = 0,
  IQR_LMS_HEIGHT_10 = 1,
  IQR_LMS_HEIGHT_5 = 2
}
 

Functions

IQR_API iqr_retval iqr_LMSCreateParams (const iqr_Context *ctx, iqr_LMSWinternitz w, iqr_LMSHeight h, const uint8_t *I, size_t I_size, iqr_LMSParams **params)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_LMSDestroyParams (iqr_LMSParams **params)
 
IQR_API iqr_retval iqr_LMSGetWinternitz (const iqr_LMSParams *params, iqr_LMSWinternitz *w)
 
IQR_API iqr_retval iqr_LMSGetHeight (const iqr_LMSParams *params, iqr_LMSHeight *h)
 
IQR_API iqr_retval iqr_LMSGetPrivateKeyIdentifier (const iqr_LMSParams *params, uint8_t *I, size_t I_size)
 
IQR_API iqr_retval iqr_LMSCreateKeyPair (const iqr_LMSParams *params, const iqr_RNG *rng, iqr_LMSPublicKey **pub_key, iqr_LMSPrivateKey **priv_key)
 
IQR_API iqr_retval iqr_LMSImportPrivateKey (const iqr_LMSParams *params, const uint8_t *data, size_t size, iqr_LMSPrivateKey **priv_key)
 
IQR_API iqr_retval iqr_LMSExportPrivateKey (const iqr_LMSPrivateKey *priv_key, uint8_t *buf, size_t buf_size)
 
IQR_API iqr_retval iqr_LMSImportPublicKey (const iqr_LMSParams *params, const uint8_t *data, size_t size, iqr_LMSPublicKey **pub_key)
 
IQR_API iqr_retval iqr_LMSExportPublicKey (const iqr_LMSPublicKey *pub_key, uint8_t *buf, size_t buf_size)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_LMSDestroyPrivateKey (iqr_LMSPrivateKey **priv_key)
 
IQR_API_UNENFORCED_RETURN iqr_retval iqr_LMSDestroyPublicKey (iqr_LMSPublicKey **pub_key)
 
IQR_API iqr_retval iqr_LMSGetPrivateKeyParams (const iqr_LMSPrivateKey *priv_key, iqr_LMSParams **params)
 
IQR_API iqr_retval iqr_LMSGetPublicKeyParams (const iqr_LMSPublicKey *pub_key, iqr_LMSParams **params)
 
IQR_API iqr_retval iqr_LMSGetPrivateKeySize (const iqr_LMSPrivateKey *priv_key, size_t *size)
 
IQR_API iqr_retval iqr_LMSGetPublicKeySize (const iqr_LMSPublicKey *pub_key, size_t *size)
 
IQR_API iqr_retval iqr_LMSGetSignatureComponentSizes (const iqr_LMSParams *params, size_t *randomizer_size, size_t *ots_sig_size, size_t *sig_path_size)
 
IQR_API iqr_retval iqr_LMSGetMaximumSignatureCount (const iqr_LMSParams *params, uint32_t *max_sigs)
 
IQR_API iqr_retval iqr_LMSGetRemainingSignatureCount (const iqr_LMSParams *params, uint32_t index, uint32_t *remaining)
 
IQR_API iqr_retval iqr_LMSSign (const iqr_LMSPrivateKey *priv_key, const iqr_RNG *rng, uint32_t index, const uint8_t *digest, size_t digest_size, uint8_t *randomizer, size_t randomizer_size, uint8_t *ots_sig, size_t ots_sig_size, uint8_t *sig_path, size_t sig_path_size)
 
IQR_API iqr_retval iqr_LMSVerify (const iqr_LMSPublicKey *pub_key, uint32_t index, const uint8_t *digest, size_t digest_size, const uint8_t *randomizer, size_t randomizer_size, const uint8_t *ots_sig, size_t ots_sig_size, const uint8_t *sig_path, size_t sig_path_size)
 

Macro Definition Documentation

§ IQR_LMS_PRIVATE_KEY_IDENTIFIER_SIZE

#define IQR_LMS_PRIVATE_KEY_IDENTIFIER_SIZE   31

The size of the LMS private key security identifier, in bytes, as defined in section 3.2 of the Hash-Based Signatures IETF Draft.

Typedef Documentation

§ iqr_LMSParams

typedef struct iqr_LMSParams_struct iqr_LMSParams

The LMS algorithm's domain parameters.

§ iqr_LMSPrivateKey

typedef struct iqr_LMSPrivateKey_struct iqr_LMSPrivateKey

The LMS private key.

§ iqr_LMSPublicKey

typedef struct iqr_LMSPublicKey_struct iqr_LMSPublicKey

The LMS public key.

Enumeration Type Documentation

§ iqr_LMSHeight

Supported LMS tree heights.

The LMS tree height, as documented in the Hash-Based Signatures IETF Draft. The height dictates the number of one-time signatures available (2height).

Enumerator
IQR_LMS_HEIGHT_20 

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

IQR_LMS_HEIGHT_10 

Provide 1024 (210) one-time signatures.

IQR_LMS_HEIGHT_5 

Provide 32 (25) one-time signatures.

§ iqr_LMSWinternitz

Supported LMS Winternitz values.

The Winternitz domain parameter, as documented in the Hash-Based Signatures IETF Draft. A higher Winternitz value will result in greater hash iterations, impacting performance.

IQR_LMS_WINTERNITZ_4 provides the best space/performance characteristics.

Enumerator
IQR_LMS_WINTERNITZ_1 
IQR_LMS_WINTERNITZ_2 
IQR_LMS_WINTERNITZ_4 
IQR_LMS_WINTERNITZ_8 

Function Documentation

§ iqr_LMSCreateKeyPair()

IQR_API iqr_retval iqr_LMSCreateKeyPair ( const iqr_LMSParams params,
const iqr_RNG rng,
iqr_LMSPublicKey **  pub_key,
iqr_LMSPrivateKey **  priv_key 
)

Generate an LMS private/public key pair.

This can take a significant amount of time, especially for IQR_LMS_HEIGHT_20.

Note
You must register a SHA-256 implementation by calling iqr_HashRegisterCallbacks() before using the LMS API.
Parameters
[in]paramsThe key parameters to use.
[in]rngA seeded random number generator.
[out]pub_keyThe resulting iqr_LMSPublicKey object.
[out]priv_keyThe resulting iqr_LMSPrivateKey object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSCreateParams()

IQR_API iqr_retval iqr_LMSCreateParams ( const iqr_Context ctx,
iqr_LMSWinternitz  w,
iqr_LMSHeight  h,
const uint8_t *  I,
size_t  I_size,
iqr_LMSParams **  params 
)

Create an LMS Parameters object that encapsulates the domain parameters for the Leighton-Micali Signature system.

To ensure post-quantum security, this LMS implementation does not support the use of SHA-256-16 (truncated) hashes, as defined in section 4.3 in the IETF specification.

The I parameter denotes a security identifier for the private key. This value must be distinct and should be chosen uniformly, at random or via a pseudo-random function. This parameter's length must be exactly 31 bytes in length.

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 SHA-256 implementation by calling iqr_HashRegisterCallbacks() before using the LMS API.
Parameters
[in]ctxA Context object.
[in]wThe Winternitz parameter (iqr_LMSWinternitz).
[in]hThe LMS tree height (iqr_LMSHeight).
[in]IThe private key identifier security string.
[in]I_sizeThe size of the private key identifier string in bytes. Must be IQR_LMS_PRIVATE_KEY_IDENTIFIER_SIZE.
[out]paramsThe iqr_LMSParams output.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSDestroyParams()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_LMSDestroyParams ( iqr_LMSParams **  params)

Clear and deallocate an LMS key parameters object.

params will be set to NULL before returning.

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

§ iqr_LMSDestroyPrivateKey()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_LMSDestroyPrivateKey ( iqr_LMSPrivateKey **  priv_key)

Clear and deallocate an LMS private key.

priv_key will be set to NULL prior to returning.

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

§ iqr_LMSDestroyPublicKey()

IQR_API_UNENFORCED_RETURN iqr_retval iqr_LMSDestroyPublicKey ( iqr_LMSPublicKey **  pub_key)

Clear and deallocate an LMS public key.

pub_key will be set to NULL prior to returning.

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

§ iqr_LMSExportPrivateKey()

IQR_API iqr_retval iqr_LMSExportPrivateKey ( const iqr_LMSPrivateKey priv_key,
uint8_t *  buf,
size_t  buf_size 
)

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

Parameters
[in]priv_keyThe private key object.
[out]bufThe destination buffer.
[in]buf_sizeSize of buf. Use @ iqr_LMSGetPrivateKeySize to get the required buffer size.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSExportPublicKey()

IQR_API iqr_retval iqr_LMSExportPublicKey ( const iqr_LMSPublicKey pub_key,
uint8_t *  buf,
size_t  buf_size 
)

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

Parameters
[in]pub_keyThe public key object.
[out]bufThe destination buffer.
[in]buf_sizeSize of buf. Use @ iqr_LMSGetPublicKeySize to get the required buffer size.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetHeight()

IQR_API iqr_retval iqr_LMSGetHeight ( const iqr_LMSParams params,
iqr_LMSHeight h 
)

Retrieve the tree height domain parameter.

Parameters
[in]paramsThe iqr_LMSParams instance.
[out]hA variable that will receive the tree height value.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetMaximumSignatureCount()

IQR_API iqr_retval iqr_LMSGetMaximumSignatureCount ( const iqr_LMSParams params,
uint32_t *  max_sigs 
)

Get the number of signatures available with the given parameters.

The total number of signatures that can be generated is based on the height of the tree.

Parameters
[in]paramsLMS domain parameters.
[out]max_sigsThe total number of signatures.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetPrivateKeyIdentifier()

IQR_API iqr_retval iqr_LMSGetPrivateKeyIdentifier ( const iqr_LMSParams params,
uint8_t *  I,
size_t  I_size 
)

Retrieve the secret identifier parameter I.

Parameters
[in]paramsThe iqr_LMSParams instance.
[out]IA buffer to receive the secret identifier I.
[in]I_sizeSize of the I buffer. Must be exactly IQR_LMS_PRIVATE_KEY_IDENTIFIER_SIZE in size.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetPrivateKeyParams()

IQR_API iqr_retval iqr_LMSGetPrivateKeyParams ( const iqr_LMSPrivateKey priv_key,
iqr_LMSParams **  params 
)

Retrieve the LMS domain parameters from an LMS private key.

Parameters
[in]priv_keyThe private key.
[out]paramsThe resulting iqr_LMSParams object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetPrivateKeySize()

IQR_API iqr_retval iqr_LMSGetPrivateKeySize ( const iqr_LMSPrivateKey priv_key,
size_t *  size 
)

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

Parameters
[in]priv_keyThe private key.
[out]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_LMSGetPublicKeyParams()

IQR_API iqr_retval iqr_LMSGetPublicKeyParams ( const iqr_LMSPublicKey pub_key,
iqr_LMSParams **  params 
)

Retrieve the LMS domain parameters from an LMS public key.

Parameters
[in]pub_keyThe public key.
[out]paramsThe resulting iqr_LMSParams object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetPublicKeySize()

IQR_API iqr_retval iqr_LMSGetPublicKeySize ( const iqr_LMSPublicKey pub_key,
size_t *  size 
)

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

Parameters
[in]pub_keyThe public key.
[out]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_LMSGetRemainingSignatureCount()

IQR_API iqr_retval iqr_LMSGetRemainingSignatureCount ( const iqr_LMSParams params,
uint32_t  index,
uint32_t *  remaining 
)

Get the number of signatures remaining.

The total number of signatures that can be generated is based on the height of the tree. As signatures are created (i.e. as index is incremented and used), the number of available signature keys is depleted.

Parameters
[in]paramsLMS domain parameters.
[in]indexThe one-time signature index.
[out]remainingThe number of signatures remaining.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetSignatureComponentSizes()

IQR_API iqr_retval iqr_LMSGetSignatureComponentSizes ( const iqr_LMSParams params,
size_t *  randomizer_size,
size_t *  ots_sig_size,
size_t *  sig_path_size 
)

Get the size of each signature component.

The size of y_size depends on the chosen Winternitz parameter and the size of path_size depends on the LMS tree height.

Parameters
[in]paramsLMS domain parameters.
[out]randomizer_sizeThe buffer size of the randomizer value used during signature creation.
[out]ots_sig_sizeThe buffer size of a partially complete OTS public key.
[out]sig_path_sizeThe size of a path buffer.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSGetWinternitz()

IQR_API iqr_retval iqr_LMSGetWinternitz ( const iqr_LMSParams params,
iqr_LMSWinternitz w 
)

Retrieve the Winternitz domain parameter.

Parameters
[in]paramsAn iqr_LMSParams instance.
[out]wA variable that will receive the Winternitz value.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSImportPrivateKey()

IQR_API iqr_retval iqr_LMSImportPrivateKey ( const iqr_LMSParams params,
const uint8_t *  data,
size_t  size,
iqr_LMSPrivateKey **  priv_key 
)

Import an LMS private key object from a buffer.

The value of size must be the same as the length given by iqr_LMSGetPrivateKeySize().

Note
You must register a SHA-256 implementation by calling iqr_HashRegisterCallbacks() before using the LMS API.
Parameters
[in]paramsLMS Key parameters. Must be the same as when the keys were created.
[in]dataA buffer that contains a private key.
[in]sizeSize, in bytes, of the private key buffer.
[out]priv_keyThe resulting iqr_LMSPrivateKey object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSImportPublicKey()

IQR_API iqr_retval iqr_LMSImportPublicKey ( const iqr_LMSParams params,
const uint8_t *  data,
size_t  size,
iqr_LMSPublicKey **  pub_key 
)

Import an LMS public key object from a buffer.

Note
You must register a SHA-256 implementation by calling iqr_HashRegisterCallbacks() before using the LMS API.
Parameters
[in]paramsLMS Key parameters. Must be the same as when the keys were created.
[in]dataA buffer containing the public key.
[in]sizeThe size of the public key buffer.
[out]pub_keyThe resulting iqr_LMSPublickey object.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSSign()

IQR_API iqr_retval iqr_LMSSign ( const iqr_LMSPrivateKey priv_key,
const iqr_RNG rng,
uint32_t  index,
const uint8_t *  digest,
size_t  digest_size,
uint8_t *  randomizer,
size_t  randomizer_size,
uint8_t *  ots_sig,
size_t  ots_sig_size,
uint8_t *  sig_path,
size_t  sig_path_size 
)

Sign a message digest using an LMS private key.

Start index at zero for a new key pair, and increment it by 1 per signing attempt. Use iqr_LMSGetSignatureCount() to obtain the number of signing keys remaining.

Warning
Reusing index is a security risk! You must save index+1 to a reliable storage medium prior to calling this function. This will thwart accidental reuse of index in the case of system failure.

The length of digest being signed must be 256-bits (32 bytes) or longer to be quantum resistant.

As signatures are generated, the priv_key can run out of signing keys. In that case, IQR_EKEYDEPLETED will be returned and the key can no longer be used for signing. Use iqr_LMSGetSignatureComponentSizes() to check if index is outside the bounds of valid one-time signature keys.

Use iqr_LMSGetSignatureSize() to obtain the required buffer sizes for the C, y, and path parameters.

Note
You must register a SHA-256 implementation by calling iqr_HashRegisterCallbacks() before using the LMS API.
Parameters
[in]priv_keyThe private key.
[in]rngA seeded Random Number Generator object.
[in]indexThe one-time signature index.
[in]digestThe message digest to be signed.
[in]digest_sizeThe size of the digest buffer.
[out]randomizerA buffer that will contain the randomizer.
[in]randomizer_sizeThe size of the C buffer.
[out]ots_sigA buffer that will contain the intermediate OTS values.
[in]ots_sig_sizeThe size of the y buffer.
[out]sig_pathA buffer that will contain the signature path.
[in]sig_path_sizeThe size of the path buffer.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

§ iqr_LMSVerify()

IQR_API iqr_retval iqr_LMSVerify ( const iqr_LMSPublicKey pub_key,
uint32_t  index,
const uint8_t *  digest,
size_t  digest_size,
const uint8_t *  randomizer,
size_t  randomizer_size,
const uint8_t *  ots_sig,
size_t  ots_sig_size,
const uint8_t *  sig_path,
size_t  sig_path_size 
)

Verify the signature of a digest using an LMS public key.

Note
You must register a SHA-256 implementation by calling iqr_HashRegisterCallbacks() before using the LMS API.
Parameters
[in]pub_keyThe public key.
[in]indexThe one-time signature index.
[in]digestThe message digest to verify.
[in]digest_sizeThe size of the digest buffer.
[out]randomizerA buffer that contains the randomizer.
[in]randomizer_sizeThe size of the C buffer.
[out]ots_sigA buffer that contains the intermediate OTS values.
[in]ots_sig_sizeThe size of the y buffer.
[out]sig_pathA buffer that contains the signature path.
[in]sig_path_sizeThe size of the path buffer.
Returns
IQR_OK on success, or a value from iqr_retval.h when an error occurs.

Detailed Description

ISARA Toolkit's Leighton-Micali One Time Signature scheme.

The Leighton-Micali Signature (LMS) scheme is defined by the Hash-Based Signatures IETF Draft specification by McGrew and Curcio.

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

Note
To ensure post-quantum security, this LMS implementation does not support the use of SHA-256-16 (truncated) hashes, as defined in section 4.3 in the IETF specification.

The LMS scheme has some fundamental differences from traditional signature schemes such as RSA or ECDSA. In particular, you'll need to manage the index value used by iqr_LMSSign() carefully. For more details, refer to the Developer's Guide.

Note
Certain functions have been marked DEPRECATED as a result of changes to the IETF draft. These functions will be replaced by ones with an updated signature in the next release.
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.