mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Update LMS
This commit is contained in:
@@ -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
102
src/lms.c
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user