mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-29 22:20:30 +00:00
Document LMS and LMOTS internal functions
Signed-off-by: Raef Coles <raef.coles@arm.com>
This commit is contained in:
parent
8738a49d0c
commit
0a967ccf9a
@ -99,6 +99,17 @@ unsigned int network_bytes_to_unsigned_int( size_t len,
|
||||
return val;
|
||||
}
|
||||
|
||||
/* Calculate the checksum digits that are appended to the end of the LMOTS digit
|
||||
* string. See NIST SP800-208 section 3.1 or RFC8554 Algorithm 2 for details of
|
||||
* the checksum algorithm.
|
||||
*
|
||||
* \param params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* \param digest The digit string to create the digest from. As
|
||||
* this does not contain a checksum, it is the same
|
||||
* size as a hash output.
|
||||
*/
|
||||
static unsigned short lmots_checksum_calculate( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char* digest )
|
||||
{
|
||||
@ -113,6 +124,29 @@ static unsigned short lmots_checksum_calculate( const mbedtls_lmots_parameters_t
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* Create the string of digest digits (in the base determined by the Winternitz
|
||||
* parameter with the checksum appended to the end (Q || cksm(Q)). See NIST
|
||||
* SP800-208 section 3.1 or RFC8554 Algorithm 3 step 5 (also used in Algorithm
|
||||
* 4b step 3) for details.
|
||||
*
|
||||
* \param params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* \param msg The message that will be hashed to create the
|
||||
* digest.
|
||||
*
|
||||
* \param msg_size The size of the message.
|
||||
*
|
||||
* \param C_random_value The random value that will be combined with the
|
||||
* message digest. This is always the same size as a
|
||||
* hash output for whichever hash algorithm is
|
||||
* determined by the parameter set.
|
||||
*
|
||||
* \param output An output containing the digit string (+
|
||||
* checksum) of length P digits (in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8, this means it is of
|
||||
* size P bytes).
|
||||
*/
|
||||
static int create_digit_array_with_checksum( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *msg,
|
||||
size_t msg_len,
|
||||
@ -176,6 +210,35 @@ exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Hash each element of the string of digits (+ checksum), producing a hash
|
||||
* output for each element. This is used in several places (by varying the
|
||||
* hash_idx_min/max_values) in order to calculate a public key from a private
|
||||
* key (RFC8554 Algorithm 1 step 4), in order to sign a message (RFC8554
|
||||
* Algorithm 3 step 5), and to calculate a public key candidate from a
|
||||
* signature and message (RFC8554 Algorithm 4b step 3).
|
||||
*
|
||||
* \param params The LMOTS parameter set, I and q values which
|
||||
* describe the key being used.
|
||||
*
|
||||
* \param x_digit_array The array of digits (of size P, 34 in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8).
|
||||
*
|
||||
* \param hash_idx_min_values An array of the starting values of the j iterator
|
||||
* for each of the members of the digit array. If
|
||||
* this value in NULL, then all iterators will start
|
||||
* at 0.
|
||||
*
|
||||
* \param hash_idx_max_values An array of the upper bound values of the j
|
||||
* iterator for each of the members of the digit
|
||||
* array. If this value in NULL, then iterator is
|
||||
* bounded to be less than 2^w - 1 (255 in the case
|
||||
* of MBEDTLS_LMOTS_SHA256_N32_W8)
|
||||
*
|
||||
* \param output An array containing a hash output for each member
|
||||
* of the digit string P. In the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8, this is of size 32 *
|
||||
* 34.
|
||||
*/
|
||||
static int hash_digit_array( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *x_digit_array,
|
||||
const unsigned char *hash_idx_min_values,
|
||||
@ -278,6 +341,21 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Combine the hashes of the digit array into a public key. This is used in
|
||||
* in order to calculate a public key from a private key (RFC8554 Algorithm 1
|
||||
* step 4), and to calculate a public key candidate from a signature and message
|
||||
* (RFC8554 Algorithm 4b step 3).
|
||||
*
|
||||
* \param params The LMOTS parameter set, I and q values which describe
|
||||
* the key being used.
|
||||
* \param y_hashed_digits The array of hashes, one hash for each digit of the
|
||||
* symbol array (which is of size P, 34 in the case of
|
||||
* MBEDTLS_LMOTS_SHA256_N32_W8)
|
||||
*
|
||||
* \param pub_key The output public key (or candidate public key in
|
||||
* case this is being run as part of signature
|
||||
* verification), in the form of a hash output.
|
||||
*/
|
||||
static int public_key_from_hashed_digit_array( const mbedtls_lmots_parameters_t *params,
|
||||
const unsigned char *y_hashed_digits,
|
||||
unsigned char *pub_key )
|
||||
|
@ -80,8 +80,27 @@
|
||||
|
||||
#define D_CONST_LEN (2)
|
||||
static const unsigned char D_LEAF_CONSTANT_BYTES[D_CONST_LEN] = {0x82, 0x82};
|
||||
static const unsigned char D_INTERNAL_CONSTANT_BYTES[D_CONST_LEN] = {0x83, 0x83};
|
||||
static const unsigned char D_INTR_CONSTANT_BYTES[D_CONST_LEN] = {0x83, 0x83};
|
||||
|
||||
|
||||
/* Calculate the value of a leaf node of the merkle tree (which is a hash of a
|
||||
* public key and some other parameters like the leaf index). This function
|
||||
* implements RFC8554 section 5.3, in the case where r >= 2^h.
|
||||
*
|
||||
* \param params The LMS parameter set, the underlying LMOTS
|
||||
* parameter set, and I value which describe the key
|
||||
* being used.
|
||||
*
|
||||
* \param pub_key The public key of the private whose index
|
||||
* corresponds to the index of this leaf node. This
|
||||
* is a hash output.
|
||||
*
|
||||
* \param r_node_idx The index of this node in the merkle tree. Note
|
||||
* that the root node of the merkle tree is
|
||||
* 1-indexed.
|
||||
*
|
||||
* \param out The output node value, which is a hash output.
|
||||
*/
|
||||
static int create_merkle_leaf_value( const mbedtls_lms_parameters_t *params,
|
||||
unsigned char *pub_key,
|
||||
unsigned int r_node_idx,
|
||||
@ -134,6 +153,28 @@ exit:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* Calculate the value of an internal node of the merkle tree (which is a hash
|
||||
* of a public key and some other parameters like the node index). This function
|
||||
* implements RFC8554 section 5.3, in the case where r < 2^h.
|
||||
*
|
||||
* \param params The LMS parameter set, the underlying LMOTS
|
||||
* parameter set, and I value which describe the key
|
||||
* being used.
|
||||
*
|
||||
* \param left_node The value of the child of this node which is on
|
||||
* the left-hand side. As with all nodes on the
|
||||
* merkle tree, this is a hash output.
|
||||
*
|
||||
* \param right_node The value of the child of this node which is on
|
||||
* the right-hand side. As with all nodes on the
|
||||
* merkle tree, this is a hash output.
|
||||
*
|
||||
* \param r_node_idx The index of this node in the merkle tree. Note
|
||||
* that the root node of the merkle tree is
|
||||
* 1-indexed.
|
||||
*
|
||||
* \param out The output node value, which is a hash output.
|
||||
*/
|
||||
static int create_merkle_internal_value( const mbedtls_lms_parameters_t *params,
|
||||
const unsigned char *left_node,
|
||||
const unsigned char *right_node,
|
||||
@ -363,6 +404,20 @@ int mbedtls_lms_verify( const mbedtls_lms_public_t *ctx,
|
||||
|
||||
#ifdef MBEDTLS_LMS_PRIVATE
|
||||
|
||||
/* Calculate a full merkle tree based on a private key. This function
|
||||
* implements RFC8554 section 5.3, and is used to generate a public key (as the
|
||||
* public key is the root node of the merkle tree).
|
||||
*
|
||||
* \param ctx The LMS private context, containing a parameter
|
||||
* set and private key material consisting of both
|
||||
* public and private OTS.
|
||||
*
|
||||
* \param tree The output tree, which is 2^(H + 1) hash outputs.
|
||||
* In the case of H=10 we have 2048 tree nodes (of
|
||||
* which 1024 of them are leaf nodes). Note that
|
||||
* because the merkle tree root is 1-indexed, the 0
|
||||
* index tree node is never used.
|
||||
*/
|
||||
static int calculate_merkle_tree( mbedtls_lms_private_t *ctx,
|
||||
unsigned char *tree )
|
||||
{
|
||||
@ -406,6 +461,18 @@ static int calculate_merkle_tree( mbedtls_lms_private_t *ctx,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Calculate a path from a leaf node of the merkle tree to the root of the tree,
|
||||
* and return the full path. This function implements RFC8554 section 5.4.1, as
|
||||
* the merkle path is the main component of an LMS signature.
|
||||
*
|
||||
* \param ctx The LMS private context, containing a parameter
|
||||
* set and private key material consisting of both
|
||||
* public and private OTS.
|
||||
*
|
||||
* \param leaf_node_id Which leaf node to calculate the path from.
|
||||
*
|
||||
* \param tree The output path, which is H hash outputs.
|
||||
*/
|
||||
static int get_merkle_path( mbedtls_lms_private_t *ctx,
|
||||
unsigned int leaf_node_id,
|
||||
unsigned char *path )
|
||||
|
Loading…
x
Reference in New Issue
Block a user