Update LMS

This commit is contained in:
Zhi Guan
2026-01-18 17:08:16 +08:00
parent 9488128154
commit 2e8d3abbc9
2 changed files with 53 additions and 65 deletions

View File

@@ -33,7 +33,7 @@ typedef uint8_t lms_hash256_t[32];
// Crosscheck with data from LMS-reference (SHA-256), except the LMS signature. // Crosscheck with data from LMS-reference (SHA-256), except the LMS signature.
#if defined(ENABLE_LMS_CROSSCHECK) && defined(ENABLE_SHA2) #if defined(ENABLE_LMS_CROSSCHECK) && defined(ENABLE_SHA2)
#define LMS_HASH256_CTX SHA256_CTX #define LMS_HASH256_CTX SHA256_CTX
#define lms_hash256_init sha256_init #define lms_hash256_init sha256_init
#define lms_hash256_update sha256_update #define lms_hash256_update sha256_update
#define lms_hash256_finish sha256_finish #define lms_hash256_finish sha256_finish
@@ -52,7 +52,7 @@ enum {
//LMOTS_SHA256_N32_W4 = 3, //LMOTS_SHA256_N32_W4 = 3,
LMOTS_SHA256_N32_W8 = 4, LMOTS_SHA256_N32_W8 = 4,
}; };
#define LMOTS_HASH256_N32_W8 LMOTS_SHA256_N32_W8 #define LMOTS_HASH256_N32_W8 LMOTS_SHA256_N32_W8
#define LMOTS_HASH256_N32_W8_NAME "LMOTS_SHA256_N32_W8" #define LMOTS_HASH256_N32_W8_NAME "LMOTS_SHA256_N32_W8"
#else #else
enum { enum {
@@ -61,7 +61,7 @@ enum {
//LMOTS_SM3_N32_W4 = 13, //LMOTS_SM3_N32_W4 = 13,
LMOTS_SM3_N32_W8 = 14, LMOTS_SM3_N32_W8 = 14,
}; };
#define LMOTS_HASH256_N32_W8 LMOTS_SM3_N32_W8 #define LMOTS_HASH256_N32_W8 LMOTS_SM3_N32_W8
#define LMOTS_HASH256_N32_W8_NAME "LMOTS_SM3_N32_W8" #define LMOTS_HASH256_N32_W8_NAME "LMOTS_SM3_N32_W8"
#endif #endif
@@ -145,8 +145,9 @@ typedef int (*lms_key_update_callback)(LMS_KEY *key);
typedef struct LMS_KEY_st { typedef struct LMS_KEY_st {
LMS_PUBLIC_KEY public_key; LMS_PUBLIC_KEY public_key;
lms_hash256_t seed; lms_hash256_t seed; // secret seed
uint32_t q; // key index uint32_t q; // key index
lms_hash256_t *tree; lms_hash256_t *tree;
lms_key_update_callback update_callback; lms_key_update_callback update_callback;
void *update_param; void *update_param;
@@ -160,11 +161,10 @@ int lms_key_set_update_callback(LMS_KEY *key, lms_key_update_callback update_cb,
int lms_key_update(LMS_KEY *key); int lms_key_update(LMS_KEY *key);
int lms_key_remaining_signs(const LMS_KEY *key, size_t *count); int lms_key_remaining_signs(const LMS_KEY *key, size_t *count);
int lms_key_get_signature_size(const LMS_KEY *key, size_t *siglen); int lms_key_get_signature_size(const LMS_KEY *key, size_t *siglen);
int lms_key_check(const LMS_KEY *key, const LMS_PUBLIC_KEY *pub);
void lms_key_cleanup(LMS_KEY *key); void lms_key_cleanup(LMS_KEY *key);
int lms_public_key_to_bytes_ex(const LMS_PUBLIC_KEY *public_key, uint8_t **out, size_t *outlen); int lms_public_key_to_bytes_ex(const LMS_PUBLIC_KEY *public_key, uint8_t **out, size_t *outlen); // called by signature_to_bytes
int lms_public_key_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in, size_t *inlen); int lms_public_key_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in, size_t *inlen); // called by signature_from_bytes
int lms_public_key_to_bytes(const LMS_KEY *key, uint8_t **out, size_t *outlen); int lms_public_key_to_bytes(const LMS_KEY *key, uint8_t **out, size_t *outlen);
int lms_public_key_from_bytes(LMS_KEY *key, const uint8_t **in, size_t *inlen); int lms_public_key_from_bytes(LMS_KEY *key, const uint8_t **in, size_t *inlen);
int lms_public_key_print(FILE *fp, int fmt, int ind, const char *label, const LMS_KEY *pub); int lms_public_key_print(FILE *fp, int fmt, int ind, const char *label, const LMS_KEY *pub);
@@ -174,7 +174,7 @@ int lms_private_key_print(FILE *fp, int fmt, int ind, const char *label, const L
typedef struct { typedef struct {
int q; // key index uint32_t q; // key index
struct { struct {
int lmots_type; int lmots_type;
lms_hash256_t C; // signature random lms_hash256_t C; // signature random

102
src/lms.c
View File

@@ -14,12 +14,6 @@
#include <gmssl/lms.h> #include <gmssl/lms.h>
#include <gmssl/x509_alg.h> #include <gmssl/x509_alg.h>
/*
* TODO:
* 1. add key_update callback
* 2. only update q, and updated elments of hss key of files
* 3. consider append only mode of files
*/
static const uint8_t D_PBLC[2] = { 0x80, 0x80 }; static const uint8_t D_PBLC[2] = { 0x80, 0x80 };
static const uint8_t D_MESG[2] = { 0x81, 0x81 }; static const uint8_t D_MESG[2] = { 0x81, 0x81 };
@@ -207,8 +201,8 @@ void lmots_compute_signature(const uint8_t I[16], int q, const lms_hash256_t dgs
void lmots_signature_to_public_hash(const uint8_t I[16], int q, const lms_hash256_t y[34], const lms_hash256_t dgst, lms_hash256_t pub) void lmots_signature_to_public_hash(const uint8_t I[16], int q, const lms_hash256_t y[34], const lms_hash256_t dgst, lms_hash256_t pub)
{ {
uint8_t checksum[2];
LMS_HASH256_CTX ctx; LMS_HASH256_CTX ctx;
uint8_t checksum[2];
lms_hash256_t z[34]; lms_hash256_t z[34];
uint8_t qbytes[4]; uint8_t qbytes[4];
uint8_t ibytes[2]; uint8_t ibytes[2];
@@ -339,19 +333,6 @@ void lms_derive_merkle_root(const lms_hash256_t seed, const uint8_t I[16], int h
memcpy(root, stack[0], 32); memcpy(root, stack[0], 32);
} }
int lms_public_key_to_bytes(const LMS_KEY *key, uint8_t **out, size_t *outlen)
{
if (!key) {
error_print();
return -1;
}
if (lms_public_key_to_bytes_ex(&key->public_key, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int lms_public_key_to_bytes_ex(const LMS_PUBLIC_KEY *public_key, uint8_t **out, size_t *outlen) int lms_public_key_to_bytes_ex(const LMS_PUBLIC_KEY *public_key, uint8_t **out, size_t *outlen)
{ {
if (!public_key || !outlen) { if (!public_key || !outlen) {
@@ -372,22 +353,6 @@ int lms_public_key_to_bytes_ex(const LMS_PUBLIC_KEY *public_key, uint8_t **out,
return 1; return 1;
} }
int lms_private_key_to_bytes(const LMS_KEY *key, uint8_t **out, size_t *outlen)
{
if (lms_public_key_to_bytes(key, out, outlen) != 1) {
error_print();
return -1;
}
if (out && *out) {
memcpy(*out, key->seed, 32);
*out += 32;
PUTU32(*out, key->q);
*out += 4;
}
*outlen += 32 + 4;
return 1;
}
int lms_public_key_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in, size_t *inlen) int lms_public_key_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in, size_t *inlen)
{ {
if (!public_key || !in || !(*in) || !inlen) { if (!public_key || !in || !(*in) || !inlen) {
@@ -398,7 +363,6 @@ int lms_public_key_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in,
error_print(); error_print();
return -1; return -1;
} }
memset(public_key, 0, sizeof(LMS_PUBLIC_KEY)); memset(public_key, 0, sizeof(LMS_PUBLIC_KEY));
public_key->lms_type = GETU32(*in); public_key->lms_type = GETU32(*in);
@@ -428,6 +392,19 @@ int lms_public_key_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in,
return 1; return 1;
} }
int lms_public_key_to_bytes(const LMS_KEY *key, uint8_t **out, size_t *outlen)
{
if (!key) {
error_print();
return -1;
}
if (lms_public_key_to_bytes_ex(&key->public_key, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int lms_public_key_from_bytes(LMS_KEY *key, const uint8_t **in, size_t *inlen) int lms_public_key_from_bytes(LMS_KEY *key, const uint8_t **in, size_t *inlen)
{ {
if (!key) { if (!key) {
@@ -442,31 +419,19 @@ int lms_public_key_from_bytes(LMS_KEY *key, const uint8_t **in, size_t *inlen)
return 1; return 1;
} }
int lms_key_check(const LMS_KEY *key, const LMS_PUBLIC_KEY *pub) int lms_private_key_to_bytes(const LMS_KEY *key, uint8_t **out, size_t *outlen)
{ {
// FIXME: implement this if (lms_public_key_to_bytes(key, out, outlen) != 1) {
return 1;
}
int lms_key_remaining_signs(const LMS_KEY *key, size_t *count)
{
size_t height;
size_t n;
if (!key || !count) {
error_print(); error_print();
return -1; return -1;
} }
if (lms_type_to_height(key->public_key.lms_type, &height) != 1) { if (out && *out) {
error_print(); memcpy(*out, key->seed, 32);
return -1; *out += 32;
PUTU32(*out, key->q);
*out += 4;
} }
n = 1 << height; *outlen += 32 + 4;
if (key->q > n) {
error_print();
return -1;
}
*count = n - key->q;
return 1; return 1;
} }
@@ -661,6 +626,29 @@ int lms_key_update(LMS_KEY *key)
return 1; return 1;
} }
int lms_key_remaining_signs(const LMS_KEY *key, size_t *count)
{
size_t height;
size_t n;
if (!key || !count) {
error_print();
return -1;
}
if (lms_type_to_height(key->public_key.lms_type, &height) != 1) {
error_print();
return -1;
}
n = 1 << height;
if (key->q > n) {
error_print();
return -1;
}
*count = n - key->q;
return 1;
}
int lms_signature_size(int lms_type, size_t *len) int lms_signature_size(int lms_type, size_t *len)
{ {
size_t height; size_t height;