Skip to content

Commit 9db11c6

Browse files
committed
Update XMSS
Add key_update callback and private_key_from_file
1 parent 2e8d3ab commit 9db11c6

File tree

4 files changed

+258
-140
lines changed

4 files changed

+258
-140
lines changed

include/gmssl/xmss.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,18 @@ typedef struct {
207207

208208
#define XMSS_PUBLIC_KEY_SIZE (4 + 32 + 32) // = 68
209209

210-
typedef struct {
210+
typedef struct XMSS_KEY_st XMSS_KEY;
211+
212+
typedef int (*xmss_key_update_callback)(XMSS_KEY *key);
213+
214+
typedef struct XMSS_KEY_st {
211215
XMSS_PUBLIC_KEY public_key;
212216
uint32_t index;
213217
xmss_hash256_t secret;
214218
xmss_hash256_t sk_prf;
215219
xmss_hash256_t *tree; // xmss_hash256_t[2^(h + 1) - 1]
220+
xmss_key_update_callback update_callback;
221+
void *update_param;
216222
} XMSS_KEY;
217223

218224
// XMSS_SHA2_10_256: 65,640
@@ -224,13 +230,17 @@ int xmss_private_key_size(uint32_t xmss_type, size_t *keysize);
224230

225231
int xmss_key_generate(XMSS_KEY *key, uint32_t xmss_type);
226232
int xmss_key_remaining_signs(const XMSS_KEY *key, size_t *count);
233+
int xmss_key_set_update_callback(XMSS_KEY *key, xmss_key_update_callback update_cb, void *param);
234+
int xmss_key_update(XMSS_KEY *key);
235+
void xmss_key_cleanup(XMSS_KEY *key);
236+
227237
int xmss_public_key_to_bytes(const XMSS_KEY *key, uint8_t **out, size_t *outlen);
228238
int xmss_public_key_from_bytes(XMSS_KEY *key, const uint8_t **in, size_t *inlen);
229239
int xmss_public_key_print(FILE *fp, int fmt, int ind, const char *label, const XMSS_KEY *key);
230240
int xmss_private_key_to_bytes(const XMSS_KEY *key, uint8_t **out, size_t *outlen);
231241
int xmss_private_key_from_bytes(XMSS_KEY *key, const uint8_t **in, size_t *inlen);
242+
int xmss_private_key_from_file(XMSS_KEY *key, FILE *fp);
232243
int xmss_private_key_print(FILE *fp, int fmt, int ind, const char *label, const XMSS_KEY *key);
233-
void xmss_key_cleanup(XMSS_KEY *key);
234244

235245

236246
typedef struct {
@@ -345,13 +355,19 @@ typedef struct {
345355

346356
#define XMSSMT_PUBLIC_KEY_SIZE (4 + sizeof(xmss_hash256_t) + sizeof(xmss_hash256_t)) // = 68 bytes
347357

348-
typedef struct {
358+
typedef struct XMSSMT_KEY_st XMSSMT_KEY;
359+
360+
typedef int (*xmssmt_key_update_callback)(XMSSMT_KEY *key);
361+
362+
typedef struct XMSSMT_KEY_st {
349363
XMSSMT_PUBLIC_KEY public_key;
350364
uint64_t index; // in [0, 2^60 - 1]
351365
xmss_hash256_t secret;
352366
xmss_hash256_t sk_prf;
353367
xmss_hash256_t *trees;
354368
xmss_wots_sig_t wots_sigs[XMSSMT_MAX_LAYERS - 1];
369+
xmssmt_key_update_callback update_callback;
370+
void *update_param;
355371
} XMSSMT_KEY;
356372

357373
/*
@@ -368,12 +384,14 @@ int xmssmt_private_key_size(uint32_t xmssmt_type, size_t *len);
368384
int xmssmt_build_auth_path(const xmss_hash256_t *tree, size_t height, size_t layers, uint64_t index, xmss_hash256_t *auth_path);
369385

370386
int xmssmt_key_generate(XMSSMT_KEY *key, uint32_t xmssmt_type);
387+
int xmssmt_key_set_update_callback(XMSSMT_KEY *key, xmssmt_key_update_callback update_cb, void *param);
371388
int xmssmt_key_update(XMSSMT_KEY *key);
372389
int xmssmt_public_key_to_bytes(const XMSSMT_KEY *key, uint8_t **out, size_t *outlen);
373390
int xmssmt_public_key_from_bytes(XMSSMT_KEY *key, const uint8_t **in, size_t *inlen);
374391
int xmssmt_public_key_print(FILE *fp, int fmt, int ind, const char *label, const XMSSMT_KEY *key);
375392
int xmssmt_private_key_to_bytes(const XMSSMT_KEY *key, uint8_t **out, size_t *outlen);
376393
int xmssmt_private_key_from_bytes(XMSSMT_KEY *key, const uint8_t **in, size_t *inlen);
394+
int xmssmt_private_key_from_file(XMSSMT_KEY *key, FILE *fp);
377395
int xmssmt_private_key_print(FILE *fp, int fmt, int ind, const char *label, const XMSSMT_KEY *key);
378396
void xmssmt_key_cleanup(XMSSMT_KEY *key);
379397

@@ -388,8 +406,7 @@ typedef struct {
388406
int xmssmt_index_to_bytes(uint64_t index, uint32_t xmssmt_type, uint8_t **out, size_t *outlen);
389407
int xmssmt_index_from_bytes(uint64_t *index, uint32_t xmssmt_type, const uint8_t **in, size_t *inlen);
390408

391-
#define XMSSMT_SIGNATURE_MAX_SIZE \
392-
(sizeof(uint64_t) + sizeof(xmss_hash256_t) + sizeof(xmss_wots_sig_t)*XMSSMT_MAX_LAYERS + sizeof(xmss_hash256_t)*XMSSMT_MAX_HEIGHT) // = 27688 bytes
409+
#define XMSSMT_SIGNATURE_MAX_SIZE sizeof(XMSSMT_SIGNATURE) // >= 27688 bytes
393410

394411
int xmssmt_key_get_signature_size(const XMSSMT_KEY *key, size_t *siglen);
395412
int xmssmt_signature_size(uint32_t xmssmt_type, size_t *siglen);

src/xmss.c

Lines changed: 176 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,17 @@ int xmss_key_generate(XMSS_KEY *key, uint32_t xmss_type)
754754
return ret;
755755
}
756756

757+
int xmss_key_set_update_callback(XMSS_KEY *key, xmss_key_update_callback update_cb, void *param)
758+
{
759+
if (!key) {
760+
error_print();
761+
return -1;
762+
}
763+
key->update_callback = update_cb;
764+
key->update_param = param;
765+
return 1;
766+
}
767+
757768
int xmss_key_update(XMSS_KEY *key)
758769
{
759770
size_t height;
@@ -774,6 +785,13 @@ int xmss_key_update(XMSS_KEY *key)
774785
return 0;
775786
}
776787
key->index++;
788+
789+
if (key->update_callback) {
790+
if (key->update_callback(key) != 1) {
791+
error_print();
792+
return -1;
793+
}
794+
}
777795
return 1;
778796
}
779797

@@ -1186,12 +1204,15 @@ int xmss_sign_init(XMSS_SIGN_CTX *ctx, XMSS_KEY *key)
11861204
xmss_adrs_set_ots_address(adrs, key->index);
11871205
xmss_wots_derive_sk(key->secret, key->public_key.seed, adrs, ctx->xmss_sig.wots_sig);
11881206

1207+
// update key->index
1208+
if (xmss_key_update(key) != 1) {
1209+
error_print();
1210+
return -1;
1211+
}
1212+
11891213
// xmss_sig.auth_path
11901214
xmss_build_auth_path(key->tree, height, key->index, ctx->xmss_sig.auth_path);
11911215

1192-
// update key->index
1193-
key->index++;
1194-
11951216
// H_msg(M) := HASH256(toByte(2, 32) || r || XMSS_ROOT || toByte(idx_sig, 32) || M)
11961217
xmss_hash256_init(&ctx->hash256_ctx);
11971218
xmss_hash256_update(&ctx->hash256_ctx, xmss_hash256_two, sizeof(xmss_hash256_t));
@@ -1575,6 +1596,17 @@ int xmssmt_private_key_from_bytes(XMSSMT_KEY *key, const uint8_t **in, size_t *i
15751596
return 1;
15761597
}
15771598

1599+
int xmssmt_key_set_update_callback(XMSSMT_KEY *key, xmssmt_key_update_callback update_cb, void *param)
1600+
{
1601+
if (!key) {
1602+
error_print();
1603+
return -1;
1604+
}
1605+
key->update_callback = update_cb;
1606+
key->update_param = param;
1607+
return 1;
1608+
}
1609+
15781610
int xmssmt_key_update(XMSSMT_KEY *key)
15791611
{
15801612
size_t height;
@@ -1628,6 +1660,12 @@ int xmssmt_key_update(XMSSMT_KEY *key)
16281660

16291661
key->index++;
16301662

1663+
if (key->update_callback) {
1664+
if (key->update_callback(key) != 1) {
1665+
error_print();
1666+
return -1;
1667+
}
1668+
}
16311669
return 1;
16321670
}
16331671

@@ -2447,3 +2485,138 @@ int xmssmt_verify_finish(XMSSMT_SIGN_CTX *ctx)
24472485

24482486
return 1;
24492487
}
2488+
2489+
int xmss_private_key_from_file(XMSS_KEY *key, FILE *fp)
2490+
{
2491+
uint8_t pubkeybuf[XMSS_PUBLIC_KEY_SIZE];
2492+
uint8_t *keybuf = NULL;
2493+
size_t keylen;
2494+
const uint8_t *cp;
2495+
size_t len;
2496+
2497+
if (!key || !fp) {
2498+
error_print();
2499+
return -1;
2500+
}
2501+
2502+
// load xmss_public_key and get xmss_private_key_size
2503+
len = sizeof(pubkeybuf);
2504+
if (fread(pubkeybuf, 1, len, fp) != len) {
2505+
error_print();
2506+
return -1;
2507+
}
2508+
cp = pubkeybuf;
2509+
if (xmss_public_key_from_bytes(key, &cp, &len) != 1) {
2510+
error_print();
2511+
return -1;
2512+
}
2513+
if (len) {
2514+
error_print();
2515+
return -1;
2516+
}
2517+
if (xmss_private_key_size(key->public_key.xmss_type, &keylen) != 1) {
2518+
error_print();
2519+
return -1;
2520+
}
2521+
if (keylen <= sizeof(pubkeybuf)) {
2522+
error_print();
2523+
return -1;
2524+
}
2525+
2526+
// malloc and load full xmss_private_key
2527+
if (!(keybuf = malloc(keylen))) {
2528+
error_print();
2529+
return -1;
2530+
}
2531+
memcpy(keybuf, pubkeybuf, sizeof(pubkeybuf));
2532+
2533+
len = keylen - sizeof(pubkeybuf);
2534+
if (fread(keybuf + sizeof(pubkeybuf), 1, len, fp) != len) {
2535+
free(keybuf);
2536+
error_print();
2537+
return -1;
2538+
}
2539+
2540+
cp = keybuf;
2541+
if (xmss_private_key_from_bytes(key, &cp, &keylen) != 1) {
2542+
free(keybuf);
2543+
error_print();
2544+
return -1;
2545+
}
2546+
if (keylen) {
2547+
free(keybuf);
2548+
error_print();
2549+
return -1;
2550+
}
2551+
2552+
free(keybuf);
2553+
return 1;
2554+
}
2555+
2556+
int xmssmt_private_key_from_file(XMSSMT_KEY *key, FILE *fp)
2557+
{
2558+
uint8_t pubkeybuf[XMSSMT_PUBLIC_KEY_SIZE];
2559+
uint8_t *keybuf = NULL;
2560+
size_t keylen;
2561+
const uint8_t *cp;
2562+
size_t len;
2563+
2564+
if (!key || !fp) {
2565+
error_print();
2566+
return -1;
2567+
}
2568+
2569+
// load xmss_public_key and get xmss_private_key_size
2570+
len = sizeof(pubkeybuf);
2571+
if (fread(pubkeybuf, 1, len, fp) != len) {
2572+
error_print();
2573+
return -1;
2574+
}
2575+
cp = pubkeybuf;
2576+
if (xmssmt_public_key_from_bytes(key, &cp, &len) != 1) {
2577+
error_print();
2578+
return -1;
2579+
}
2580+
if (len) {
2581+
error_print();
2582+
return -1;
2583+
}
2584+
if (xmssmt_private_key_size(key->public_key.xmssmt_type, &keylen) != 1) {
2585+
error_print();
2586+
return -1;
2587+
}
2588+
if (keylen <= sizeof(pubkeybuf)) {
2589+
error_print();
2590+
return -1;
2591+
}
2592+
2593+
// malloc and load full xmss_private_key
2594+
if (!(keybuf = malloc(keylen))) {
2595+
error_print();
2596+
return -1;
2597+
}
2598+
memcpy(keybuf, pubkeybuf, sizeof(pubkeybuf));
2599+
2600+
len = keylen - sizeof(pubkeybuf);
2601+
if (fread(keybuf + sizeof(pubkeybuf), 1, len, fp) != len) {
2602+
free(keybuf);
2603+
error_print();
2604+
return -1;
2605+
}
2606+
2607+
cp = keybuf;
2608+
if (xmssmt_private_key_from_bytes(key, &cp, &keylen) != 1) {
2609+
free(keybuf);
2610+
error_print();
2611+
return -1;
2612+
}
2613+
if (keylen) {
2614+
free(keybuf);
2615+
error_print();
2616+
return -1;
2617+
}
2618+
2619+
free(keybuf);
2620+
return 1;
2621+
}
2622+

0 commit comments

Comments
 (0)