From 2e8d3abbc9e3bc73ddbd8c5a611424765f07e228 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Sun, 18 Jan 2026 17:08:16 +0800 Subject: [PATCH] Update LMS --- include/gmssl/lms.h | 16 +++---- src/lms.c | 102 +++++++++++++++++++------------------------- 2 files changed, 53 insertions(+), 65 deletions(-) diff --git a/include/gmssl/lms.h b/include/gmssl/lms.h index f0b04974..2c85c6a5 100644 --- a/include/gmssl/lms.h +++ b/include/gmssl/lms.h @@ -33,7 +33,7 @@ typedef uint8_t lms_hash256_t[32]; // Crosscheck with data from LMS-reference (SHA-256), except the LMS signature. #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_update sha256_update #define lms_hash256_finish sha256_finish @@ -52,7 +52,7 @@ enum { //LMOTS_SHA256_N32_W4 = 3, 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" #else enum { @@ -61,7 +61,7 @@ enum { //LMOTS_SM3_N32_W4 = 13, 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" #endif @@ -145,8 +145,9 @@ typedef int (*lms_key_update_callback)(LMS_KEY *key); typedef struct LMS_KEY_st { LMS_PUBLIC_KEY public_key; - lms_hash256_t seed; + lms_hash256_t seed; // secret seed uint32_t q; // key index + lms_hash256_t *tree; lms_key_update_callback update_callback; 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_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_check(const LMS_KEY *key, const LMS_PUBLIC_KEY *pub); 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_from_bytes_ex(LMS_PUBLIC_KEY *public_key, const uint8_t **in, size_t *inlen); +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); // 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_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); @@ -174,7 +174,7 @@ int lms_private_key_print(FILE *fp, int fmt, int ind, const char *label, const L typedef struct { - int q; // key index + uint32_t q; // key index struct { int lmots_type; lms_hash256_t C; // signature random diff --git a/src/lms.c b/src/lms.c index cbf4657c..8d279bf5 100644 --- a/src/lms.c +++ b/src/lms.c @@ -14,12 +14,6 @@ #include #include -/* - * 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_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) { - uint8_t checksum[2]; LMS_HASH256_CTX ctx; + uint8_t checksum[2]; lms_hash256_t z[34]; uint8_t qbytes[4]; 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); } -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) { 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; } -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) { 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(); return -1; } - memset(public_key, 0, sizeof(LMS_PUBLIC_KEY)); 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; } +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) { if (!key) { @@ -442,31 +419,19 @@ int lms_public_key_from_bytes(LMS_KEY *key, const uint8_t **in, size_t *inlen) 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 - return 1; -} - -int lms_key_remaining_signs(const LMS_KEY *key, size_t *count) -{ - size_t height; - size_t n; - - if (!key || !count) { + if (lms_public_key_to_bytes(key, out, outlen) != 1) { error_print(); return -1; } - if (lms_type_to_height(key->public_key.lms_type, &height) != 1) { - error_print(); - return -1; + if (out && *out) { + memcpy(*out, key->seed, 32); + *out += 32; + PUTU32(*out, key->q); + *out += 4; } - n = 1 << height; - if (key->q > n) { - error_print(); - return -1; - } - *count = n - key->q; + *outlen += 32 + 4; return 1; } @@ -661,6 +626,29 @@ int lms_key_update(LMS_KEY *key) 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) { size_t height;