mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Update XMSS-SM3
XMSS is in developing, not fully tested
This commit is contained in:
@@ -54,7 +54,7 @@ option(ENABLE_SM4_CBC_MAC "Enable SM4-CBC-MAC" ON)
|
|||||||
|
|
||||||
option(ENABLE_SM2_EXTS "Enable SM2 Extensions" OFF)
|
option(ENABLE_SM2_EXTS "Enable SM2 Extensions" OFF)
|
||||||
option(ENABLE_LMS_HSS "Enable LMS/HSS signature" ON)
|
option(ENABLE_LMS_HSS "Enable LMS/HSS signature" ON)
|
||||||
option(ENABLE_SM3_XMSS "Enable SM3-XMSS signature" OFF)
|
option(ENABLE_XMSS "Enable XMSS/XMSS^MT signature" OFF)
|
||||||
|
|
||||||
|
|
||||||
option(ENABLE_SHA1 "Enable SHA1" ON)
|
option(ENABLE_SHA1 "Enable SHA1" ON)
|
||||||
@@ -432,16 +432,17 @@ if (ENABLE_LMS_HSS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if (ENABLE_SM3_XMSS)
|
if (ENABLE_XMSS)
|
||||||
message(STATUS "ENABLE_SM3_XMSS is ON")
|
message(STATUS "ENABLE_XMSS is ON")
|
||||||
add_definitions(-DENABLE_SM3_XMSS)
|
add_definitions(-DENABLE_XMSS)
|
||||||
list(APPEND src src/sm3_xmss.c)
|
list(APPEND src src/xmss.c)
|
||||||
|
list(APPEND tools tools/xmsskeygen.c tools/xmsssign.c tools/xmssverify.c)
|
||||||
|
list(APPEND tests xmss)
|
||||||
|
|
||||||
option(ENABLE_SM3_XMSS_CROSSCHECK "Enable XMSS SHA-256 cross-check" OFF)
|
option(ENABLE_XMSS_CROSSCHECK "Enable XMSS SHA-256 cross-check" ON)
|
||||||
if (ENABLE_SM3_XMSS_CROSSCHECK)
|
if (ENABLE_XMSS_CROSSCHECK)
|
||||||
message(STATUS "ENABLE_SM3_XMSS_CROSSCHECK is ON")
|
message(STATUS "ENABLE_XMSS_CROSSCHECK is ON")
|
||||||
add_definitions(-DENABLE_SM3_XMSS_CROSSCHECK)
|
add_definitions(-DENABLE_XMSS_CROSSCHECK)
|
||||||
list(APPEND tests sm3_xmss)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
28
include/gmssl/hash256.h
Normal file
28
include/gmssl/hash256.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014-2025 The GmSSL Project. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GMSSL_HASH256_H
|
||||||
|
#define GMSSL_HASH256_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint8_t hash256_t[32];
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -10,28 +10,22 @@
|
|||||||
#ifndef GMSSL_LMS_H
|
#ifndef GMSSL_LMS_H
|
||||||
#define GMSSL_LMS_H
|
#define GMSSL_LMS_H
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <gmssl/sm3.h>
|
#include <gmssl/sm3.h>
|
||||||
|
#include <gmssl/hash256.h>
|
||||||
#ifdef ENABLE_SHA2
|
#ifdef ENABLE_SHA2
|
||||||
#include <gmssl/sha2.h>
|
#include <gmssl/sha2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef uint8_t hash256_t[32];
|
|
||||||
|
|
||||||
|
|
||||||
#define HSS_MAX_LEVELS 5
|
#define HSS_MAX_LEVELS 5
|
||||||
#define LMS_MAX_HEIGHT 25
|
#define LMS_MAX_HEIGHT 25
|
||||||
|
|
||||||
|
|||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
|
||||||
* not use this file except in compliance with the License.
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef GMSSL_SM3_XMSS_H
|
|
||||||
#define GMSSL_SM3_XMSS_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <gmssl/sm3.h>
|
|
||||||
#ifdef ENABLE_SHA2
|
|
||||||
#include <gmssl/sha2.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Crosscheck with data from xmss-reference (SHA-256), except the XMSS signature.
|
|
||||||
#if defined(ENABLE_SM3_XMSS_CROSSCHECK) && defined(ENABLE_SHA2)
|
|
||||||
# define HASH256_CTX SHA256_CTX
|
|
||||||
# define hash256_init sha256_init
|
|
||||||
# define hash256_update sha256_update
|
|
||||||
# define hash256_finish sha256_finish
|
|
||||||
# define hash256_digest sha256_digest
|
|
||||||
#else
|
|
||||||
# define HASH256_CTX SM3_CTX
|
|
||||||
# define hash256_init sm3_init
|
|
||||||
# define hash256_update sm3_update
|
|
||||||
# define hash256_finish sm3_finish
|
|
||||||
# define hash256_digest sm3_digest
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef uint8_t hash256_bytes_t[32];
|
|
||||||
|
|
||||||
// Derive wots+ sk from a secret seed use the spec of xmss-reference.
|
|
||||||
void sm3_wots_derive_sk(const uint8_t secret[32],
|
|
||||||
const uint8_t seed[32], const uint8_t in_adrs[32],
|
|
||||||
hash256_bytes_t sk[67]);
|
|
||||||
void sm3_wots_derive_pk(const hash256_bytes_t sk[67],
|
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
|
||||||
hash256_bytes_t pk[67]);
|
|
||||||
void sm3_wots_do_sign(const hash256_bytes_t sk[67],
|
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
|
||||||
const uint8_t dgst[32], hash256_bytes_t sig[67]);
|
|
||||||
void sm3_wots_sig_to_pk(const hash256_bytes_t sig[67], const uint8_t dgst[32],
|
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
|
||||||
hash256_bytes_t pk[67]);
|
|
||||||
|
|
||||||
void sm3_xmss_derive_root(const uint8_t xmss_secret[32], int height,
|
|
||||||
const uint8_t seed[32],
|
|
||||||
hash256_bytes_t *tree, uint8_t xmss_root[32]);
|
|
||||||
void sm3_xmss_do_sign(const uint8_t xmss_secret[32], int index,
|
|
||||||
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
|
||||||
const hash256_bytes_t *tree,
|
|
||||||
const uint8_t dgst[32],
|
|
||||||
hash256_bytes_t wots_sig[67],
|
|
||||||
hash256_bytes_t *auth_path);
|
|
||||||
|
|
||||||
void sm3_xmss_sig_to_root(const hash256_bytes_t wots_sig[67], int index, const hash256_bytes_t *auth_path,
|
|
||||||
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
|
||||||
const uint8_t dgst[32],
|
|
||||||
uint8_t xmss_root[32]);
|
|
||||||
|
|
||||||
enum {
|
|
||||||
XMSS_SM3_10 = 0x10000001,
|
|
||||||
XMSS_SM3_16 = 0x10000002,
|
|
||||||
XMSS_SM3_20 = 0x10000003,
|
|
||||||
XMSS_SHA256_10 = 0x00000001,
|
|
||||||
XMSS_SHA256_16 = 0x00000002,
|
|
||||||
XMSS_SHA256_20 = 0x00000003,
|
|
||||||
};
|
|
||||||
|
|
||||||
int sm3_xmss_height_from_oid(uint32_t *height, uint32_t id);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t oid;
|
|
||||||
uint8_t seed[32];
|
|
||||||
uint8_t root[32];
|
|
||||||
uint8_t secret[32];
|
|
||||||
uint8_t prf_key[32];
|
|
||||||
uint32_t index;
|
|
||||||
hash256_bytes_t *tree;
|
|
||||||
} SM3_XMSS_KEY;
|
|
||||||
|
|
||||||
int sm3_xmss_key_generate(SM3_XMSS_KEY *key, uint32_t oid);
|
|
||||||
int sm3_xmss_key_print(FILE *fp, int fmt, int ind, const char *label, const SM3_XMSS_KEY *key);
|
|
||||||
int sm3_xmss_key_get_height(const SM3_XMSS_KEY *key, uint32_t *height);
|
|
||||||
int sm3_xmss_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *outlen);
|
|
||||||
int sm3_xmss_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t inlen);
|
|
||||||
int sm3_xmss_public_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *outlen);
|
|
||||||
int sm3_xmss_public_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t inlen);
|
|
||||||
void sm3_xmss_key_cleanup(SM3_XMSS_KEY *key);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t index[4];
|
|
||||||
uint8_t random[32];
|
|
||||||
hash256_bytes_t wots_sig[67];
|
|
||||||
hash256_bytes_t auth_path[20];
|
|
||||||
} SM3_XMSS_SIGNATURE;
|
|
||||||
|
|
||||||
int sm3_xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *in, size_t inlen);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t random[32];
|
|
||||||
HASH256_CTX hash256_ctx;
|
|
||||||
} SM3_XMSS_SIGN_CTX;
|
|
||||||
|
|
||||||
int sm3_xmss_sign_init(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key);
|
|
||||||
int sm3_xmss_sign_update(SM3_XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
|
|
||||||
int sm3_xmss_sign_finish(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, uint8_t *sigbuf, size_t *siglen);
|
|
||||||
int sm3_xmss_verify_init(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen);
|
|
||||||
int sm3_xmss_verify_update(SM3_XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
|
|
||||||
int sm3_xmss_verify_finish(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
181
include/gmssl/xmss.h
Normal file
181
include/gmssl/xmss.h
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014-2025 The GmSSL Project. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GMSSL_XMSS_H
|
||||||
|
#define GMSSL_XMSS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <gmssl/sm3.h>
|
||||||
|
#include <gmssl/hash256.h>
|
||||||
|
#ifdef ENABLE_SHA2
|
||||||
|
#include <gmssl/sha2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Crosscheck with data from xmss-reference (SHA-256), except the XMSS signature.
|
||||||
|
#if defined(ENABLE_XMSS_CROSSCHECK) && defined(ENABLE_SHA2)
|
||||||
|
# define HASH256_CTX SHA256_CTX
|
||||||
|
# define hash256_init sha256_init
|
||||||
|
# define hash256_update sha256_update
|
||||||
|
# define hash256_finish sha256_finish
|
||||||
|
# define hash256_digest sha256_digest
|
||||||
|
# define LMS_HASH256_10 XMSS_SHA256_10
|
||||||
|
# define LMS_HASH256_16 XMSS_SHA256_16
|
||||||
|
# define LMS_HASH256_20 XMSS_SHA256_20
|
||||||
|
#else
|
||||||
|
# define HASH256_CTX SM3_CTX
|
||||||
|
# define hash256_init sm3_init
|
||||||
|
# define hash256_update sm3_update
|
||||||
|
# define hash256_finish sm3_finish
|
||||||
|
# define hash256_digest sm3_digest
|
||||||
|
# define LMS_HASH256_10 XMSS_SM3_10
|
||||||
|
# define LMS_HASH256_16 XMSS_SM3_16
|
||||||
|
# define LMS_HASH256_20 XMSS_SM3_20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define XMSS_MIX_HEIGHT 16
|
||||||
|
#define XMSS_MAX_HEIGHT 20
|
||||||
|
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// * change uint8[32] to hash256_t
|
||||||
|
// * key_to_bytes, from_bytes, use **out, *outlen style
|
||||||
|
// * support private key/ public key functions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Derive wots+ sk from a secret seed use the spec of xmss-reference.
|
||||||
|
void sm3_wots_derive_sk(const uint8_t secret[32],
|
||||||
|
const uint8_t seed[32], const uint8_t in_adrs[32],
|
||||||
|
hash256_t sk[67]); // change number 67 to a DEFINE
|
||||||
|
void sm3_wots_derive_pk(const hash256_t sk[67],
|
||||||
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
|
hash256_t pk[67]);
|
||||||
|
void sm3_wots_do_sign(const hash256_t sk[67],
|
||||||
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
|
const uint8_t dgst[32], hash256_t sig[67]);
|
||||||
|
void sm3_wots_sig_to_pk(const hash256_t sig[67], const uint8_t dgst[32],
|
||||||
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
|
hash256_t pk[67]);
|
||||||
|
|
||||||
|
void xmss_derive_root(const uint8_t xmss_secret[32], int height,
|
||||||
|
const uint8_t seed[32],
|
||||||
|
hash256_t *tree, uint8_t xmss_root[32]);
|
||||||
|
void xmss_do_sign(const uint8_t xmss_secret[32], int index,
|
||||||
|
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
||||||
|
const hash256_t *tree,
|
||||||
|
const uint8_t dgst[32],
|
||||||
|
hash256_t wots_sig[67],
|
||||||
|
hash256_t *auth_path);
|
||||||
|
|
||||||
|
void xmss_sig_to_root(const hash256_t wots_sig[67], int index, const hash256_t *auth_path,
|
||||||
|
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
||||||
|
const uint8_t dgst[32],
|
||||||
|
uint8_t xmss_root[32]);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
XMSS_SM3_10 = 0x10000001,
|
||||||
|
XMSS_SM3_16 = 0x10000002,
|
||||||
|
XMSS_SM3_20 = 0x10000003,
|
||||||
|
XMSS_SHA256_10 = 0x00000001,
|
||||||
|
XMSS_SHA256_16 = 0x00000002,
|
||||||
|
XMSS_SHA256_20 = 0x00000003,
|
||||||
|
};
|
||||||
|
|
||||||
|
// delete this func
|
||||||
|
int xmss_height_from_oid(uint32_t *height, uint32_t id);
|
||||||
|
|
||||||
|
|
||||||
|
// PK = OID || root || SEED
|
||||||
|
// SK = idx || wots_sk || SK_PRF || root || SEED;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t oid;
|
||||||
|
uint8_t seed[32];
|
||||||
|
uint8_t root[32];
|
||||||
|
|
||||||
|
uint8_t secret[32];
|
||||||
|
uint8_t prf_key[32];
|
||||||
|
uint32_t index; // change this to int, update every signing
|
||||||
|
hash256_t *tree;
|
||||||
|
} XMSS_KEY;
|
||||||
|
|
||||||
|
|
||||||
|
#define XMSS_PUBLIC_KEY_SIZE (4 + 32 + 32) // = 68
|
||||||
|
#define XMSS_PRIVATE_KEY_SIZE (XMSS_PUBLIC_KEY_SIZE + 32 + 32 + 4) // = 136
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: add public_key, private_key funcs
|
||||||
|
// TODO: key_update func
|
||||||
|
// TODO: build tree in private_key_from_bytes
|
||||||
|
int xmss_key_generate(XMSS_KEY *key, uint32_t oid);
|
||||||
|
int xmss_key_print(FILE *fp, int fmt, int ind, const char *label, const XMSS_KEY *key);
|
||||||
|
int xmss_key_get_height(const XMSS_KEY *key, uint32_t *height);
|
||||||
|
int xmss_key_to_bytes(const XMSS_KEY *key, uint8_t *out, size_t *outlen);
|
||||||
|
int xmss_key_from_bytes(XMSS_KEY *key, const uint8_t *in, size_t inlen);
|
||||||
|
int xmss_public_key_to_bytes(const XMSS_KEY *key, uint8_t *out, size_t *outlen);
|
||||||
|
int xmss_public_key_from_bytes(XMSS_KEY *key, const uint8_t *in, size_t inlen);
|
||||||
|
void xmss_key_cleanup(XMSS_KEY *key);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t index[4];
|
||||||
|
uint8_t random[32];
|
||||||
|
hash256_t wots_sig[67];
|
||||||
|
hash256_t auth_path[XMSS_MAX_HEIGHT];
|
||||||
|
} XMSS_SIGNATURE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// XMSS_SM3_10_256 2500 bytes
|
||||||
|
// XMSS_SM3_16_256 2692 bytes
|
||||||
|
// XMSS_SM3_20_256 2820 bytes
|
||||||
|
#define XMSS_SIGNATURE_MIN_SIZE (4 + 32 + 32*67 + 32 * XMSS_MIN_HEIGHT) // = 2500 bytes
|
||||||
|
#define XMSS_SIGNATURE_MAX_SIZE (4 + 32 + 32*67 + 32 * XMSS_MAX_HEIGHT) // = 2820 bytes
|
||||||
|
|
||||||
|
int xmss_signature_size(uint32_t oid, size_t *siglen);
|
||||||
|
|
||||||
|
// TODO: impl this
|
||||||
|
int xmss_key_get_signature_size(const XMSS_KEY *key, size_t siglen);
|
||||||
|
|
||||||
|
int xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *in, size_t inlen);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t random[32];
|
||||||
|
HASH256_CTX hash256_ctx;
|
||||||
|
// TODO: cache signing key
|
||||||
|
} XMSS_SIGN_CTX;
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: change the API to LMS/HSS style
|
||||||
|
// TODO: remove const before XMSS_KEY in sign_init
|
||||||
|
int xmss_sign_init(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key);
|
||||||
|
int xmss_sign_update(XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
|
||||||
|
int xmss_sign_finish(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key, uint8_t *sigbuf, size_t *siglen);
|
||||||
|
int xmss_verify_init(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen);
|
||||||
|
int xmss_verify_update(XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
|
||||||
|
int xmss_verify_finish(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
#include <gmssl/hex.h>
|
#include <gmssl/hex.h>
|
||||||
#include <gmssl/rand.h>
|
#include <gmssl/rand.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
#include <gmssl/sm3_xmss.h>
|
#include <gmssl/xmss.h>
|
||||||
|
|
||||||
|
|
||||||
#define uint32_from_bytes(ptr) \
|
#define uint32_from_bytes(ptr) \
|
||||||
@@ -134,6 +134,8 @@ static void hash256_prf_keygen_init(HASH256_CTX *hash256_ctx, const uint8_t key[
|
|||||||
hash256_update(hash256_ctx, key, 32);
|
hash256_update(hash256_ctx, key, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute wots+ chain, start from the secret x or a signature, output the final value
|
||||||
|
// 最终的这个结果应该不是PK啊?
|
||||||
static void wots_chain(const uint8_t x[32], int start, int steps,
|
static void wots_chain(const uint8_t x[32], int start, int steps,
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32], uint8_t pk[32])
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32], uint8_t pk[32])
|
||||||
{
|
{
|
||||||
@@ -173,7 +175,7 @@ static void wots_chain(const uint8_t x[32], int start, int steps,
|
|||||||
memcpy(pk, state, 32);
|
memcpy(pk, state, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_wots_derive_sk(const uint8_t secret[32], const uint8_t seed[32], const uint8_t in_adrs[32], hash256_bytes_t sk[67])
|
void sm3_wots_derive_sk(const uint8_t secret[32], const uint8_t seed[32], const uint8_t in_adrs[32], hash256_t sk[67])
|
||||||
{
|
{
|
||||||
HASH256_CTX prf_keygen_ctx;
|
HASH256_CTX prf_keygen_ctx;
|
||||||
HASH256_CTX prf_ctx;
|
HASH256_CTX prf_ctx;
|
||||||
@@ -196,9 +198,9 @@ void sm3_wots_derive_sk(const uint8_t secret[32], const uint8_t seed[32], const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_wots_derive_pk(const hash256_bytes_t sk[67],
|
void sm3_wots_derive_pk(const hash256_t sk[67],
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
hash256_bytes_t pk[67])
|
hash256_t pk[67])
|
||||||
{
|
{
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
int i;
|
int i;
|
||||||
@@ -238,9 +240,9 @@ static void base_w_and_checksum(const uint8_t dgst[32], uint8_t msg[67])
|
|||||||
msg[66] = csum_bytes[1] >> 4;
|
msg[66] = csum_bytes[1] >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_wots_do_sign(const hash256_bytes_t sk[67],
|
void sm3_wots_do_sign(const hash256_t sk[67],
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
const uint8_t dgst[32], hash256_bytes_t sig[67])
|
const uint8_t dgst[32], hash256_t sig[67])
|
||||||
{
|
{
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
uint8_t msg[67];
|
uint8_t msg[67];
|
||||||
@@ -256,9 +258,9 @@ void sm3_wots_do_sign(const hash256_bytes_t sk[67],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_wots_sig_to_pk(const hash256_bytes_t sig[67], const uint8_t dgst[32],
|
void sm3_wots_sig_to_pk(const hash256_t sig[67], const uint8_t dgst[32],
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
hash256_bytes_t pk[67])
|
hash256_t pk[67])
|
||||||
{
|
{
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
uint8_t msg[67];
|
uint8_t msg[67];
|
||||||
@@ -311,11 +313,11 @@ static void randomized_hash(const uint8_t left[32], const uint8_t right[32],
|
|||||||
hash256_finish(&hash256_ctx, out);
|
hash256_finish(&hash256_ctx, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_ltree(const hash256_bytes_t in_pk[67],
|
static void build_ltree(const hash256_t in_pk[67],
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
uint8_t wots_root[32])
|
uint8_t wots_root[32])
|
||||||
{
|
{
|
||||||
hash256_bytes_t pk[67];
|
hash256_t pk[67];
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
uint32_t tree_height = 0;
|
uint32_t tree_height = 0;
|
||||||
int len = 67;
|
int len = 67;
|
||||||
@@ -344,9 +346,9 @@ static void build_ltree(const hash256_bytes_t in_pk[67],
|
|||||||
|
|
||||||
// len(tree) = 2^h - 1
|
// len(tree) = 2^h - 1
|
||||||
// root = tree[len(tree) - 1] = tree[2^h - 2]
|
// root = tree[len(tree) - 1] = tree[2^h - 2]
|
||||||
static void build_hash_tree(const hash256_bytes_t *leaves, int height,
|
static void build_hash_tree(const hash256_t *leaves, int height,
|
||||||
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
const HASH256_CTX *prf_seed_ctx, const uint8_t in_adrs[32],
|
||||||
hash256_bytes_t *tree)
|
hash256_t *tree)
|
||||||
{
|
{
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
int n = 1 << height;
|
int n = 1 << height;
|
||||||
@@ -368,9 +370,9 @@ static void build_hash_tree(const hash256_bytes_t *leaves, int height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_xmss_derive_root(const uint8_t xmss_secret[32], int height,
|
void xmss_derive_root(const uint8_t xmss_secret[32], int height,
|
||||||
const uint8_t seed[32],
|
const uint8_t seed[32],
|
||||||
hash256_bytes_t *tree, uint8_t xmss_root[32])
|
hash256_t *tree, uint8_t xmss_root[32])
|
||||||
{
|
{
|
||||||
HASH256_CTX prf_keygen_ctx;
|
HASH256_CTX prf_keygen_ctx;
|
||||||
HASH256_CTX prf_seed_ctx;
|
HASH256_CTX prf_seed_ctx;
|
||||||
@@ -383,8 +385,8 @@ void sm3_xmss_derive_root(const uint8_t xmss_secret[32], int height,
|
|||||||
// generate all the wots pk[]
|
// generate all the wots pk[]
|
||||||
for (i = 0; i < (uint32_t)(1<<height); i++) {
|
for (i = 0; i < (uint32_t)(1<<height); i++) {
|
||||||
//HASH256_CTX prf_ctx = prf_keygen_ctx;
|
//HASH256_CTX prf_ctx = prf_keygen_ctx;
|
||||||
hash256_bytes_t wots_sk[67];
|
hash256_t wots_sk[67];
|
||||||
hash256_bytes_t wots_pk[67];
|
hash256_t wots_pk[67];
|
||||||
|
|
||||||
// xmss_secret => wots_sk[0..67] => wots_pk[0..67]
|
// xmss_secret => wots_sk[0..67] => wots_pk[0..67]
|
||||||
// follow github.com/XMSS/xmss-reference
|
// follow github.com/XMSS/xmss-reference
|
||||||
@@ -405,7 +407,7 @@ void sm3_xmss_derive_root(const uint8_t xmss_secret[32], int height,
|
|||||||
memcpy(xmss_root, tree + (1 << (height + 1)) - 2, 32);
|
memcpy(xmss_root, tree + (1 << (height + 1)) - 2, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_auth_path(const hash256_bytes_t *tree, int height, int index, hash256_bytes_t *path)
|
static void build_auth_path(const hash256_t *tree, int height, int index, hash256_t *path)
|
||||||
{
|
{
|
||||||
int h;
|
int h;
|
||||||
for (h = 0; h < height; h++) {
|
for (h = 0; h < height; h++) {
|
||||||
@@ -415,16 +417,16 @@ static void build_auth_path(const hash256_bytes_t *tree, int height, int index,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_xmss_do_sign(const uint8_t xmss_secret[32], int index,
|
void xmss_do_sign(const uint8_t xmss_secret[32], int index,
|
||||||
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
||||||
const hash256_bytes_t *tree,
|
const hash256_t *tree,
|
||||||
const uint8_t dgst[32],
|
const uint8_t dgst[32],
|
||||||
hash256_bytes_t wots_sig[67],
|
hash256_t wots_sig[67],
|
||||||
hash256_bytes_t *auth_path)
|
hash256_t *auth_path)
|
||||||
{
|
{
|
||||||
HASH256_CTX prf_seed_ctx;
|
HASH256_CTX prf_seed_ctx;
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
hash256_bytes_t wots_sk[67];
|
hash256_t wots_sk[67];
|
||||||
|
|
||||||
hash256_prf_init(&prf_seed_ctx, seed);
|
hash256_prf_init(&prf_seed_ctx, seed);
|
||||||
memcpy(adrs, in_adrs, 32);
|
memcpy(adrs, in_adrs, 32);
|
||||||
@@ -439,14 +441,14 @@ void sm3_xmss_do_sign(const uint8_t xmss_secret[32], int index,
|
|||||||
build_auth_path(tree, height, index, auth_path);
|
build_auth_path(tree, height, index, auth_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_xmss_sig_to_root(const hash256_bytes_t wots_sig[67], int index, const hash256_bytes_t *auth_path,
|
void xmss_sig_to_root(const hash256_t wots_sig[67], int index, const hash256_t *auth_path,
|
||||||
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
const uint8_t seed[32], const uint8_t in_adrs[32], int height,
|
||||||
const uint8_t dgst[32],
|
const uint8_t dgst[32],
|
||||||
uint8_t xmss_root[32])
|
uint8_t xmss_root[32])
|
||||||
{
|
{
|
||||||
HASH256_CTX prf_seed_ctx;
|
HASH256_CTX prf_seed_ctx;
|
||||||
uint8_t adrs[32];
|
uint8_t adrs[32];
|
||||||
hash256_bytes_t wots_pk[67];
|
hash256_t wots_pk[67];
|
||||||
uint8_t *node = xmss_root;
|
uint8_t *node = xmss_root;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
@@ -475,7 +477,7 @@ void sm3_xmss_sig_to_root(const hash256_bytes_t wots_sig[67], int index, const h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_height_from_oid(uint32_t *height, uint32_t id)
|
int xmss_height_from_oid(uint32_t *height, uint32_t id)
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case XMSS_SM3_10: *height = 10; break;
|
case XMSS_SM3_10: *height = 10; break;
|
||||||
@@ -491,11 +493,27 @@ int sm3_xmss_height_from_oid(uint32_t *height, uint32_t id)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_key_generate(SM3_XMSS_KEY *key, uint32_t oid)
|
int xmss_oid_to_height(uint32_t oid, size_t *height)
|
||||||
|
{
|
||||||
|
switch (oid) {
|
||||||
|
case XMSS_SM3_10: *height = 10; break;
|
||||||
|
case XMSS_SM3_16: *height = 16; break;
|
||||||
|
case XMSS_SM3_20: *height = 20; break;
|
||||||
|
case XMSS_SHA256_10: *height = 10; break;
|
||||||
|
case XMSS_SHA256_16: *height = 16; break;
|
||||||
|
case XMSS_SHA256_20: *height = 20; break;
|
||||||
|
default:
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xmss_key_generate(XMSS_KEY *key, uint32_t oid)
|
||||||
{
|
{
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
|
||||||
if (sm3_xmss_height_from_oid(&height, oid) != 1) {
|
if (xmss_height_from_oid(&height, oid) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -509,12 +527,12 @@ int sm3_xmss_key_generate(SM3_XMSS_KEY *key, uint32_t oid)
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sm3_xmss_derive_root(key->secret, height, key->seed, key->tree, key->root);
|
xmss_derive_root(key->secret, height, key->seed, key->tree, key->root);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sm3_xmss_key_cleanup(SM3_XMSS_KEY *key)
|
void xmss_key_cleanup(XMSS_KEY *key)
|
||||||
{
|
{
|
||||||
if (key->tree) {
|
if (key->tree) {
|
||||||
free(key->tree);
|
free(key->tree);
|
||||||
@@ -522,7 +540,7 @@ void sm3_xmss_key_cleanup(SM3_XMSS_KEY *key)
|
|||||||
gmssl_secure_clear(key, sizeof(*key));
|
gmssl_secure_clear(key, sizeof(*key));
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_key_print(FILE *fp, int fmt, int ind, const char *label, const SM3_XMSS_KEY *key)
|
int xmss_key_print(FILE *fp, int fmt, int ind, const char *label, const XMSS_KEY *key)
|
||||||
{
|
{
|
||||||
format_print(fp, fmt, ind, "%s\n", label);
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
ind += 4;
|
ind += 4;
|
||||||
@@ -535,16 +553,18 @@ int sm3_xmss_key_print(FILE *fp, int fmt, int ind, const char *label, const SM3_
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_key_get_height(const SM3_XMSS_KEY *key, uint32_t *height)
|
|
||||||
|
int xmss_key_get_height(const XMSS_KEY *key, uint32_t *height)
|
||||||
{
|
{
|
||||||
if (sm3_xmss_height_from_oid(height, key->oid) != 1) {
|
if (xmss_height_from_oid(height, key->oid) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *outlen)
|
// save the full tree, should use a flag to choose cache tree or not
|
||||||
|
int xmss_key_to_bytes(const XMSS_KEY *key, uint8_t *out, size_t *outlen)
|
||||||
{
|
{
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
size_t tree_size;
|
size_t tree_size;
|
||||||
@@ -555,7 +575,7 @@ int sm3_xmss_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *outlen)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_height_from_oid(&height, key->oid) != 1) {
|
if (xmss_height_from_oid(&height, key->oid) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -583,7 +603,7 @@ int sm3_xmss_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *outlen)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t inlen)
|
int xmss_key_from_bytes(XMSS_KEY *key, const uint8_t *in, size_t inlen)
|
||||||
{
|
{
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
size_t tree_size;
|
size_t tree_size;
|
||||||
@@ -596,7 +616,7 @@ int sm3_xmss_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t inlen)
|
|||||||
p = in;
|
p = in;
|
||||||
key->oid = uint32_from_bytes(p); p += 4;
|
key->oid = uint32_from_bytes(p); p += 4;
|
||||||
|
|
||||||
if (sm3_xmss_height_from_oid(&height, key->oid) != 1) {
|
if (xmss_height_from_oid(&height, key->oid) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -624,7 +644,7 @@ int sm3_xmss_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t inlen)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_public_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *outlen)
|
int xmss_public_key_to_bytes(const XMSS_KEY *key, uint8_t *out, size_t *outlen)
|
||||||
{
|
{
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
@@ -634,7 +654,7 @@ int sm3_xmss_public_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_height_from_oid(&height, key->oid) != 1) {
|
if (xmss_height_from_oid(&height, key->oid) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -654,7 +674,7 @@ int sm3_xmss_public_key_to_bytes(const SM3_XMSS_KEY *key, uint8_t *out, size_t *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: check input length
|
// FIXME: check input length
|
||||||
int sm3_xmss_public_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t inlen)
|
int xmss_public_key_from_bytes(XMSS_KEY *key, const uint8_t *in, size_t inlen)
|
||||||
{
|
{
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
@@ -665,7 +685,7 @@ int sm3_xmss_public_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t
|
|||||||
}
|
}
|
||||||
p = in;
|
p = in;
|
||||||
key->oid = uint32_from_bytes(p); p += 4;
|
key->oid = uint32_from_bytes(p); p += 4;
|
||||||
if (sm3_xmss_height_from_oid(&height, key->oid) != 1) {
|
if (xmss_height_from_oid(&height, key->oid) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -674,10 +694,10 @@ int sm3_xmss_public_key_from_bytes(SM3_XMSS_KEY *key, const uint8_t *in, size_t
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *in, size_t inlen)
|
int xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *in, size_t inlen)
|
||||||
{
|
{
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
SM3_XMSS_SIGNATURE *sig = (SM3_XMSS_SIGNATURE *)in;
|
XMSS_SIGNATURE *sig = (XMSS_SIGNATURE *)in;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
format_print(fp, fmt, ind, "%s\n", label);
|
format_print(fp, fmt, ind, "%s\n", label);
|
||||||
@@ -693,7 +713,7 @@ int sm3_xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, cons
|
|||||||
}
|
}
|
||||||
format_print(fp, fmt, ind, "auth_path\n");
|
format_print(fp, fmt, ind, "auth_path\n");
|
||||||
|
|
||||||
assert(sizeof(SM3_XMSS_SIGNATURE) == 4 + 32 * (68 + 20));
|
assert(sizeof(XMSS_SIGNATURE) == 4 + 32 * (68 + 20));
|
||||||
inlen -= 4 + 32 * 68;
|
inlen -= 4 + 32 * 68;
|
||||||
for (i = 0; i < 20 && inlen >= 32; i++) {
|
for (i = 0; i < 20 && inlen >= 32; i++) {
|
||||||
format_print(fp, fmt, ind+4, "%d ", i);
|
format_print(fp, fmt, ind+4, "%d ", i);
|
||||||
@@ -704,7 +724,31 @@ int sm3_xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, cons
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_sign_init(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key)
|
|
||||||
|
// (4 + n + (len + h) * n)
|
||||||
|
int xmss_signature_size(uint32_t oid, size_t *siglen)
|
||||||
|
{
|
||||||
|
size_t height;
|
||||||
|
|
||||||
|
if (!siglen) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (xmss_oid_to_height(oid, &height) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*siglen = 4 // OID
|
||||||
|
+ 32 // random
|
||||||
|
+ 32 * 67 // WOTS signature size
|
||||||
|
+ 32 * height // path
|
||||||
|
;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int xmss_sign_init(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key)
|
||||||
{
|
{
|
||||||
HASH256_CTX prf_ctx;
|
HASH256_CTX prf_ctx;
|
||||||
uint8_t hash_id[32] = {0};
|
uint8_t hash_id[32] = {0};
|
||||||
@@ -727,7 +771,7 @@ int sm3_xmss_sign_init(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_sign_update(SM3_XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
int xmss_sign_update(XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
||||||
{
|
{
|
||||||
if (data && datalen) {
|
if (data && datalen) {
|
||||||
hash256_update(&ctx->hash256_ctx, data, datalen);
|
hash256_update(&ctx->hash256_ctx, data, datalen);
|
||||||
@@ -735,17 +779,17 @@ int sm3_xmss_sign_update(SM3_XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t dat
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_sign_finish(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, uint8_t *sigbuf, size_t *siglen)
|
int xmss_sign_finish(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key, uint8_t *sigbuf, size_t *siglen)
|
||||||
{
|
{
|
||||||
SM3_XMSS_SIGNATURE *sig = (SM3_XMSS_SIGNATURE *)sigbuf;
|
XMSS_SIGNATURE *sig = (XMSS_SIGNATURE *)sigbuf;
|
||||||
uint8_t adrs[32] = {0};
|
uint8_t adrs[32] = {0};
|
||||||
uint8_t dgst[32];
|
uint8_t dgst[32];
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
|
||||||
hash256_finish(&ctx->hash256_ctx, dgst);
|
hash256_finish(&ctx->hash256_ctx, dgst);
|
||||||
|
|
||||||
sm3_xmss_key_get_height(key, &height);
|
xmss_key_get_height(key, &height);
|
||||||
sm3_xmss_do_sign(key->secret, key->index, key->seed, adrs, height, key->tree, dgst,
|
xmss_do_sign(key->secret, key->index, key->seed, adrs, height, key->tree, dgst,
|
||||||
sig->wots_sig, sig->auth_path);
|
sig->wots_sig, sig->auth_path);
|
||||||
|
|
||||||
uint32_to_bytes(key->index, sig->index);
|
uint32_to_bytes(key->index, sig->index);
|
||||||
@@ -755,9 +799,9 @@ int sm3_xmss_sign_finish(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, uint8_
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_verify_init(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen)
|
int xmss_verify_init(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen)
|
||||||
{
|
{
|
||||||
SM3_XMSS_SIGNATURE *sig = (SM3_XMSS_SIGNATURE *)sigbuf;
|
XMSS_SIGNATURE *sig = (XMSS_SIGNATURE *)sigbuf;
|
||||||
uint8_t hash_id[32] = {0};
|
uint8_t hash_id[32] = {0};
|
||||||
uint8_t index_buf[32] = {0};
|
uint8_t index_buf[32] = {0};
|
||||||
|
|
||||||
@@ -773,7 +817,7 @@ int sm3_xmss_verify_init(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_verify_update(SM3_XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
int xmss_verify_update(XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
||||||
{
|
{
|
||||||
if (data && datalen) {
|
if (data && datalen) {
|
||||||
hash256_update(&ctx->hash256_ctx, data, datalen);
|
hash256_update(&ctx->hash256_ctx, data, datalen);
|
||||||
@@ -781,10 +825,10 @@ int sm3_xmss_verify_update(SM3_XMSS_SIGN_CTX *ctx, const uint8_t *data, size_t d
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm3_xmss_verify_finish(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen)
|
int xmss_verify_finish(XMSS_SIGN_CTX *ctx, const XMSS_KEY *key, const uint8_t *sigbuf, size_t siglen)
|
||||||
{
|
{
|
||||||
|
|
||||||
const SM3_XMSS_SIGNATURE *sig = (const SM3_XMSS_SIGNATURE *)sigbuf;
|
const XMSS_SIGNATURE *sig = (const XMSS_SIGNATURE *)sigbuf;
|
||||||
uint8_t adrs[32] = {0};
|
uint8_t adrs[32] = {0};
|
||||||
uint8_t dgst[32];
|
uint8_t dgst[32];
|
||||||
uint32_t index, height;
|
uint32_t index, height;
|
||||||
@@ -792,10 +836,10 @@ int sm3_xmss_verify_finish(SM3_XMSS_SIGN_CTX *ctx, const SM3_XMSS_KEY *key, cons
|
|||||||
|
|
||||||
hash256_finish(&ctx->hash256_ctx, dgst);
|
hash256_finish(&ctx->hash256_ctx, dgst);
|
||||||
|
|
||||||
sm3_xmss_key_get_height(key, &height);
|
xmss_key_get_height(key, &height);
|
||||||
index = uint32_from_bytes(sig->index);
|
index = uint32_from_bytes(sig->index);
|
||||||
|
|
||||||
sm3_xmss_sig_to_root(sig->wots_sig, index, sig->auth_path, key->seed, adrs, height, dgst, xmss_root);
|
xmss_sig_to_root(sig->wots_sig, index, sig->auth_path, key->seed, adrs, height, dgst, xmss_root);
|
||||||
|
|
||||||
if (memcmp(xmss_root, key->root, 32) != 0) {
|
if (memcmp(xmss_root, key->root, 32) != 0) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gmssl/hex.h>
|
#include <gmssl/hex.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
#include <gmssl/sm3_xmss.h>
|
#include <gmssl/xmss.h>
|
||||||
|
|
||||||
|
|
||||||
// copy this static function from src/sm3_xmss.c
|
// copy this static function from src/sm3_xmss.c
|
||||||
@@ -31,8 +31,8 @@ static int test_sm3_wots_derive_sk(void)
|
|||||||
uint8_t wots_secret[32] = {0};
|
uint8_t wots_secret[32] = {0};
|
||||||
uint8_t seed[32] = {0};
|
uint8_t seed[32] = {0};
|
||||||
uint8_t adrs[32] = {0};
|
uint8_t adrs[32] = {0};
|
||||||
hash256_bytes_t wots_sk[67];
|
hash256_t wots_sk[67];
|
||||||
hash256_bytes_t test_sk[67];
|
hash256_t test_sk[67];
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
// sha256 test 1
|
// sha256 test 1
|
||||||
@@ -76,9 +76,9 @@ static int test_sm3_wots_derive_pk(void)
|
|||||||
uint8_t wots_secret[32] = {0};
|
uint8_t wots_secret[32] = {0};
|
||||||
uint8_t seed[32] = {0};
|
uint8_t seed[32] = {0};
|
||||||
uint8_t adrs[32] = {0};
|
uint8_t adrs[32] = {0};
|
||||||
hash256_bytes_t wots_sk[67];
|
hash256_t wots_sk[67];
|
||||||
hash256_bytes_t wots_pk[67];
|
hash256_t wots_pk[67];
|
||||||
hash256_bytes_t test_pk[67];
|
hash256_t test_pk[67];
|
||||||
HASH256_CTX prf_seed_ctx;
|
HASH256_CTX prf_seed_ctx;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
@@ -111,11 +111,11 @@ static int test_sm3_wots_do_sign(void)
|
|||||||
uint8_t seed[32] = {0};
|
uint8_t seed[32] = {0};
|
||||||
uint8_t adrs[32] = {0};
|
uint8_t adrs[32] = {0};
|
||||||
uint8_t dgst[32] = {0};
|
uint8_t dgst[32] = {0};
|
||||||
hash256_bytes_t wots_sk[67];
|
hash256_t wots_sk[67];
|
||||||
hash256_bytes_t wots_pk[67];
|
hash256_t wots_pk[67];
|
||||||
hash256_bytes_t wots_sig[67];
|
hash256_t wots_sig[67];
|
||||||
hash256_bytes_t test_sig[67];
|
hash256_t test_sig[67];
|
||||||
hash256_bytes_t sig_pk[67];
|
hash256_t sig_pk[67];
|
||||||
HASH256_CTX prf_seed_ctx;
|
HASH256_CTX prf_seed_ctx;
|
||||||
size_t len;
|
size_t len;
|
||||||
int i;
|
int i;
|
||||||
@@ -154,12 +154,12 @@ static int test_sm3_wots_do_sign(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_sm3_xmss_derive_root(void)
|
static int test_xmss_derive_root(void)
|
||||||
{
|
{
|
||||||
uint8_t xmss_secret[32];
|
uint8_t xmss_secret[32];
|
||||||
uint8_t seed[32];
|
uint8_t seed[32];
|
||||||
int height = 10;
|
int height = 10;
|
||||||
hash256_bytes_t *tree = malloc(32 * (1<<height) * 2);
|
hash256_t *tree = malloc(32 * (1<<height) * 2);
|
||||||
uint8_t xmss_root[32];
|
uint8_t xmss_root[32];
|
||||||
uint8_t test_root[32];
|
uint8_t test_root[32];
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -168,7 +168,7 @@ static int test_sm3_xmss_derive_root(void)
|
|||||||
memset(seed, 0xab, 32);
|
memset(seed, 0xab, 32);
|
||||||
hex_to_bytes("f0415ed807c8f8c2ee8ca3a00178bff37e1ccb2836e02607d06131c9341e52ca", 64, test_root, &len);
|
hex_to_bytes("f0415ed807c8f8c2ee8ca3a00178bff37e1ccb2836e02607d06131c9341e52ca", 64, test_root, &len);
|
||||||
|
|
||||||
sm3_xmss_derive_root(xmss_secret, height, seed, tree, xmss_root);
|
xmss_derive_root(xmss_secret, height, seed, tree, xmss_root);
|
||||||
|
|
||||||
if (memcmp(xmss_root, test_root, 32)) {
|
if (memcmp(xmss_root, test_root, 32)) {
|
||||||
error_print();
|
error_print();
|
||||||
@@ -180,7 +180,7 @@ static int test_sm3_xmss_derive_root(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int test_sm3_xmss_do_sign(void)
|
static int test_xmss_do_sign(void)
|
||||||
{
|
{
|
||||||
uint8_t xmss_secret[32];
|
uint8_t xmss_secret[32];
|
||||||
uint8_t xmss_root[32];
|
uint8_t xmss_root[32];
|
||||||
@@ -188,9 +188,9 @@ static int test_sm3_xmss_do_sign(void)
|
|||||||
uint8_t dgst[32];
|
uint8_t dgst[32];
|
||||||
uint8_t seed[32];
|
uint8_t seed[32];
|
||||||
uint8_t adrs[32] = {0};
|
uint8_t adrs[32] = {0};
|
||||||
hash256_bytes_t wots_sig[67];
|
hash256_t wots_sig[67];
|
||||||
hash256_bytes_t *auth_path = malloc(32 * h);
|
hash256_t *auth_path = malloc(32 * h);
|
||||||
hash256_bytes_t *tree = malloc(32 * (1<<h) * 2);
|
hash256_t *tree = malloc(32 * (1<<h) * 2);
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
@@ -200,12 +200,12 @@ static int test_sm3_xmss_do_sign(void)
|
|||||||
dgst[i] = i;
|
dgst[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
sm3_xmss_derive_root(xmss_secret, h, seed, tree, xmss_root);
|
xmss_derive_root(xmss_secret, h, seed, tree, xmss_root);
|
||||||
|
|
||||||
for (index = 0; index < (1<<h); index++) {
|
for (index = 0; index < (1<<h); index++) {
|
||||||
uint8_t root_from_sig[32];
|
uint8_t root_from_sig[32];
|
||||||
sm3_xmss_do_sign(xmss_secret, index, seed, adrs, h, tree, dgst, wots_sig, auth_path);
|
xmss_do_sign(xmss_secret, index, seed, adrs, h, tree, dgst, wots_sig, auth_path);
|
||||||
sm3_xmss_sig_to_root(wots_sig, index, auth_path, seed, adrs, h, dgst, root_from_sig);
|
xmss_sig_to_root(wots_sig, index, auth_path, seed, adrs, h, dgst, root_from_sig);
|
||||||
if (memcmp(xmss_root, root_from_sig, 32) != 0) {
|
if (memcmp(xmss_root, root_from_sig, 32) != 0) {
|
||||||
printf("xmss_sig_to_root failed\n");
|
printf("xmss_sig_to_root failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -216,40 +216,40 @@ static int test_sm3_xmss_do_sign(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int test_sm3_xmss_sign(void)
|
static int test_xmss_sign(void)
|
||||||
{
|
{
|
||||||
#if defined(ENABLE_SHA2) && defined(ENABLE_SM3_XMSS_CROSSCHECK)
|
#if defined(ENABLE_SHA2) && defined(ENABLE_XMSS_CROSSCHECK)
|
||||||
uint32_t oid = XMSS_SHA256_10;
|
uint32_t oid = XMSS_SHA256_10;
|
||||||
#else
|
#else
|
||||||
uint32_t oid = XMSS_SM3_10;
|
uint32_t oid = XMSS_SM3_10;
|
||||||
#endif
|
#endif
|
||||||
SM3_XMSS_KEY key;
|
XMSS_KEY key;
|
||||||
SM3_XMSS_SIGN_CTX sign_ctx;
|
XMSS_SIGN_CTX sign_ctx;
|
||||||
uint8_t sig[sizeof(SM3_XMSS_SIGNATURE)];
|
uint8_t sig[sizeof(XMSS_SIGNATURE)];
|
||||||
size_t siglen;
|
size_t siglen;
|
||||||
uint8_t msg[100] = {0};
|
uint8_t msg[100] = {0};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sm3_xmss_key_generate(&key, oid);
|
xmss_key_generate(&key, oid);
|
||||||
sm3_xmss_key_print(stderr, 0, 0, "XMSS Key", &key);
|
xmss_key_print(stderr, 0, 0, "XMSS Key", &key);
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
sm3_xmss_sign_init(&sign_ctx, &key);
|
xmss_sign_init(&sign_ctx, &key);
|
||||||
sm3_xmss_sign_update(&sign_ctx, msg, sizeof(msg));
|
xmss_sign_update(&sign_ctx, msg, sizeof(msg));
|
||||||
sm3_xmss_sign_finish(&sign_ctx, &key, sig, &siglen);
|
xmss_sign_finish(&sign_ctx, &key, sig, &siglen);
|
||||||
|
|
||||||
(key.index)++;
|
(key.index)++;
|
||||||
|
|
||||||
sm3_xmss_signature_print(stderr, 0, 0, "XMSS Signature", sig, siglen);
|
xmss_signature_print(stderr, 0, 0, "XMSS Signature", sig, siglen);
|
||||||
|
|
||||||
sm3_xmss_verify_init(&sign_ctx, &key, sig, siglen);
|
xmss_verify_init(&sign_ctx, &key, sig, siglen);
|
||||||
sm3_xmss_verify_update(&sign_ctx, msg, sizeof(msg));
|
xmss_verify_update(&sign_ctx, msg, sizeof(msg));
|
||||||
if (sm3_xmss_verify_finish(&sign_ctx, &key, sig, siglen) != 1) {
|
if (xmss_verify_finish(&sign_ctx, &key, sig, siglen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sm3_xmss_key_cleanup(&key);
|
xmss_key_cleanup(&key);
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
printf("%s() ok\n", __FUNCTION__);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -260,9 +260,9 @@ int main(void)
|
|||||||
if (test_sm3_wots_derive_sk() != 1) goto err;
|
if (test_sm3_wots_derive_sk() != 1) goto err;
|
||||||
if (test_sm3_wots_derive_pk() != 1) goto err;
|
if (test_sm3_wots_derive_pk() != 1) goto err;
|
||||||
if (test_sm3_wots_do_sign() != 1) goto err;
|
if (test_sm3_wots_do_sign() != 1) goto err;
|
||||||
if (test_sm3_xmss_derive_root() != 1) goto err;
|
if (test_xmss_derive_root() != 1) goto err;
|
||||||
if (test_sm3_xmss_do_sign() != 1) goto err;
|
if (test_xmss_do_sign() != 1) goto err;
|
||||||
if (test_sm3_xmss_sign() != 1) goto err;
|
if (test_xmss_sign() != 1) goto err;
|
||||||
printf("%s all tests passed\n", __FILE__);
|
printf("%s all tests passed\n", __FILE__);
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
@@ -72,8 +72,10 @@ extern int hsskeygen_main(int argc, char **argv);
|
|||||||
extern int hsssign_main(int argc, char **argv);
|
extern int hsssign_main(int argc, char **argv);
|
||||||
extern int hssverify_main(int argc, char **argv);
|
extern int hssverify_main(int argc, char **argv);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SM3_XMSS
|
#ifdef ENABLE_XMSS
|
||||||
extern int sm3xmss_keygen_main(int argc, char **argv);
|
extern int xmsskeygen_main(int argc, char **argv);
|
||||||
|
extern int xmsssign_main(int argc, char **argv);
|
||||||
|
extern int xmssverify_main(int argc, char **argv);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SDF
|
#ifdef ENABLE_SDF
|
||||||
extern int sdfinfo_main(int argc, char **argv);
|
extern int sdfinfo_main(int argc, char **argv);
|
||||||
@@ -140,15 +142,17 @@ static const char *options =
|
|||||||
" cmssign Generate CMS SignedData\n"
|
" cmssign Generate CMS SignedData\n"
|
||||||
" cmsverify Verify CMS SignedData\n"
|
" cmsverify Verify CMS SignedData\n"
|
||||||
#ifdef ENABLE_LMS_HSS
|
#ifdef ENABLE_LMS_HSS
|
||||||
" lmskeygen Generate SM3-LMS keypair\n"
|
" lmskeygen Generate LMS-SM3 (Leighton-Micali Signature) keypair\n"
|
||||||
" lmssign Generate LMS signature\n"
|
" lmssign Generate LMS-SM3 signature\n"
|
||||||
" lmsverify Verify LMS signature\n"
|
" lmsverify Verify LMS-SM3 signature\n"
|
||||||
" hsskeygen Generate SM3-HSS keypair\n"
|
" hsskeygen Generate HSS-SM3 keypair\n"
|
||||||
" hsssign Generate HSS signature\n"
|
" hsssign Generate HSS-SM3 signature\n"
|
||||||
" hssverify Verify HSS signature\n"
|
" hssverify Verify HSS-SM3 signature\n"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SM3_XMSS
|
#ifdef ENABLE_XMSS
|
||||||
" sm3xmss_keygen Generate SM3-XMSS keypair\n"
|
" xmsskeygen Generate XMSS-SM3 keypair\n"
|
||||||
|
" xmsssign Generate XMSS-SM3 signature\n"
|
||||||
|
" xmssverify Verify XMSS-SM3 signature\n"
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SDF
|
#ifdef ENABLE_SDF
|
||||||
" sdfinfo Print SDF device info\n"
|
" sdfinfo Print SDF device info\n"
|
||||||
@@ -318,9 +322,13 @@ int main(int argc, char **argv)
|
|||||||
} else if (!strcmp(*argv, "hssverify")) {
|
} else if (!strcmp(*argv, "hssverify")) {
|
||||||
return hssverify_main(argc, argv);
|
return hssverify_main(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SM3_XMSS
|
#ifdef ENABLE_XMSS
|
||||||
} else if (!strcmp(*argv, "sm3xmss_keygen")) {
|
} else if (!strcmp(*argv, "xmsskeygen")) {
|
||||||
return sm3xmss_keygen_main(argc, argv);
|
return xmsskeygen_main(argc, argv);
|
||||||
|
} else if (!strcmp(*argv, "xmsssign")) {
|
||||||
|
return xmsssign_main(argc, argv);
|
||||||
|
} else if (!strcmp(*argv, "xmssverify")) {
|
||||||
|
return xmssverify_main(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SDF
|
#ifdef ENABLE_SDF
|
||||||
} else if (!strcmp(*argv, "sdfinfo")) {
|
} else if (!strcmp(*argv, "sdfinfo")) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gmssl/mem.h>
|
#include <gmssl/mem.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
#include <gmssl/sm3_xmss.h>
|
#include <gmssl/xmss.h>
|
||||||
|
|
||||||
|
|
||||||
static const char *usage = "-oid oid [-out file] [-pubout file]\n";
|
static const char *usage = "-oid oid [-out file] [-pubout file]\n";
|
||||||
@@ -29,7 +29,7 @@ static const char *help =
|
|||||||
" -pubout file Output public key\n"
|
" -pubout file Output public key\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
int sm3xmss_keygen_main(int argc, char **argv)
|
int xmsskeygen_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
char *prog = argv[0];
|
char *prog = argv[0];
|
||||||
@@ -39,7 +39,7 @@ int sm3xmss_keygen_main(int argc, char **argv)
|
|||||||
char *puboutfile = NULL;
|
char *puboutfile = NULL;
|
||||||
FILE *outfp = stdout;
|
FILE *outfp = stdout;
|
||||||
FILE *puboutfp = stdout;
|
FILE *puboutfp = stdout;
|
||||||
SM3_XMSS_KEY key;
|
XMSS_KEY key;
|
||||||
uint8_t *out = NULL;
|
uint8_t *out = NULL;
|
||||||
uint8_t *pubout = NULL;
|
uint8_t *pubout = NULL;
|
||||||
size_t outlen, puboutlen;
|
size_t outlen, puboutlen;
|
||||||
@@ -103,12 +103,12 @@ bad:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sm3_xmss_key_generate(&key, oid_val) != 1) {
|
if (xmss_key_generate(&key, oid_val) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_key_to_bytes(&key, NULL, &outlen) != 1) {
|
if (xmss_key_to_bytes(&key, NULL, &outlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -116,11 +116,11 @@ bad:
|
|||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (sm3_xmss_key_to_bytes(&key, out, &outlen) != 1) {
|
if (xmss_key_to_bytes(&key, out, &outlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_public_key_to_bytes(&key, NULL, &puboutlen) != 1) {
|
if (xmss_public_key_to_bytes(&key, NULL, &puboutlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -128,7 +128,7 @@ bad:
|
|||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (sm3_xmss_public_key_to_bytes(&key, pubout, &puboutlen) != 1) {
|
if (xmss_public_key_to_bytes(&key, pubout, &puboutlen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -12,8 +12,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <gmssl/mem.h>
|
||||||
|
#include <gmssl/file.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
#include <gmssl/sm3_xmss.h>
|
#include <gmssl/xmss.h>
|
||||||
|
|
||||||
static const char *usage = "-key file [-in file] [-out file]\n";
|
static const char *usage = "-key file [-in file] [-out file]\n";
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ static const char *help =
|
|||||||
" -out file Output signature file\n"
|
" -out file Output signature file\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
int sm3xmss_sign_main(int argc, char **argv)
|
int xmsssign_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
char *prog = argv[0];
|
char *prog = argv[0];
|
||||||
@@ -34,8 +36,10 @@ int sm3xmss_sign_main(int argc, char **argv)
|
|||||||
FILE *keyfp = NULL;
|
FILE *keyfp = NULL;
|
||||||
FILE *infp = stdin;
|
FILE *infp = stdin;
|
||||||
FILE *outfp = stdout;
|
FILE *outfp = stdout;
|
||||||
SM3_XMSS_KEY key;
|
uint8_t *keybuf = NULL;
|
||||||
SM3_XMSS_SIGN_CTX sign_ctx;
|
size_t keylen;
|
||||||
|
XMSS_KEY key;
|
||||||
|
XMSS_SIGN_CTX sign_ctx;
|
||||||
uint8_t *sigbuf = NULL;
|
uint8_t *sigbuf = NULL;
|
||||||
size_t siglen;
|
size_t siglen;
|
||||||
|
|
||||||
@@ -56,10 +60,16 @@ int sm3xmss_sign_main(int argc, char **argv)
|
|||||||
} else if (!strcmp(*argv, "-key")) {
|
} else if (!strcmp(*argv, "-key")) {
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
keyfile = *(++argv);
|
keyfile = *(++argv);
|
||||||
|
/*
|
||||||
if (!(keyfp = fopen(keyfile, "rb"))) {
|
if (!(keyfp = fopen(keyfile, "rb"))) {
|
||||||
fprintf(stderr, "%s: open '%s' failure: %s\n", prog, keyfile, strerror(errno));
|
fprintf(stderr, "%s: open '%s' failure: %s\n", prog, keyfile, strerror(errno));
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
if (file_read_all(keyfile, &keybuf, &keylen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
} else if (!strcmp(*argv, "-in")) {
|
} else if (!strcmp(*argv, "-in")) {
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
infile = *(++argv);
|
infile = *(++argv);
|
||||||
@@ -91,17 +101,13 @@ bad:
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_key_from_bytes(&key, NULL, 0) != 1) {
|
|
||||||
|
if (xmss_key_from_bytes(&key, keybuf, keylen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fread(&key, 1, sizeof(key), keyfp) != sizeof(key)) {
|
if (xmss_sign_init(&sign_ctx, &key) != 1) {
|
||||||
fprintf(stderr, "%s: read private key failure\n", prog);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm3_xmss_sign_init(&sign_ctx, &key) != 1) {
|
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -112,13 +118,13 @@ bad:
|
|||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sm3_xmss_sign_update(&sign_ctx, buf, len) != 1) {
|
if (xmss_sign_update(&sign_ctx, buf, len) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_sign_finish(&sign_ctx, &key, NULL, &siglen) != 1) {
|
if (xmss_sign_finish(&sign_ctx, &key, NULL, &siglen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -128,7 +134,7 @@ bad:
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm3_xmss_sign_finish(&sign_ctx, &key, sigbuf, &siglen) != 1) {
|
if (xmss_sign_finish(&sign_ctx, &key, sigbuf, &siglen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -147,7 +153,11 @@ end:
|
|||||||
gmssl_secure_clear(sigbuf, siglen);
|
gmssl_secure_clear(sigbuf, siglen);
|
||||||
free(sigbuf);
|
free(sigbuf);
|
||||||
}
|
}
|
||||||
if (keyfp) fclose(keyfp);
|
if (keybuf) {
|
||||||
|
gmssl_secure_clear(keybuf, keylen);
|
||||||
|
free(keybuf);
|
||||||
|
}
|
||||||
|
//if (keyfp) fclose(keyfp);
|
||||||
if (infp && infp != stdin) fclose(infp);
|
if (infp && infp != stdin) fclose(infp);
|
||||||
if (outfp && outfp != stdout) fclose(outfp);
|
if (outfp && outfp != stdout) fclose(outfp);
|
||||||
return ret;
|
return ret;
|
||||||
158
tools/xmssverify.c
Normal file
158
tools/xmssverify.c
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014-2025 The GmSSL Project. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <gmssl/mem.h>
|
||||||
|
#include <gmssl/error.h>
|
||||||
|
#include <gmssl/xmss.h>
|
||||||
|
|
||||||
|
static const char *usage = "-pubkey file [-in file] -sig file [-verbose]\n";
|
||||||
|
|
||||||
|
static const char *options =
|
||||||
|
"Options\n"
|
||||||
|
" -pubkey file Input public key file\n"
|
||||||
|
" -in file Input data file (if not using stdin)\n"
|
||||||
|
" -sig file Input signature file\n"
|
||||||
|
" -verbose Print public key and signature\n"
|
||||||
|
"\n";
|
||||||
|
|
||||||
|
int xmssverify_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
char *prog = argv[0];
|
||||||
|
char *pubkeyfile = NULL;
|
||||||
|
char *infile = NULL;
|
||||||
|
char *sigfile = NULL;
|
||||||
|
int verbose = 0;
|
||||||
|
FILE *pubkeyfp = NULL;
|
||||||
|
FILE *infp = stdin;
|
||||||
|
FILE *sigfp = NULL;
|
||||||
|
uint8_t pubkeybuf[XMSS_PUBLIC_KEY_SIZE];
|
||||||
|
size_t pubkeylen = XMSS_PUBLIC_KEY_SIZE;
|
||||||
|
const uint8_t *cp = pubkeybuf;
|
||||||
|
uint8_t sig[XMSS_SIGNATURE_MAX_SIZE];
|
||||||
|
size_t siglen;
|
||||||
|
XMSS_KEY key;
|
||||||
|
XMSS_SIGN_CTX ctx;
|
||||||
|
int vr;
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
fprintf(stderr, "usage: gmssl %s %s\n", prog, usage);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (argc > 0) {
|
||||||
|
if (!strcmp(*argv, "-help")) {
|
||||||
|
printf("usage: %s %s\n", prog, usage);
|
||||||
|
printf("%s\n", options);
|
||||||
|
ret = 0;
|
||||||
|
goto end;
|
||||||
|
} else if (!strcmp(*argv, "-pubkey")) {
|
||||||
|
if (--argc < 1) goto bad;
|
||||||
|
pubkeyfile = *(++argv);
|
||||||
|
if (!(pubkeyfp = fopen(pubkeyfile, "rb"))) {
|
||||||
|
fprintf(stderr, "%s: open '%s' failure: %s\n", prog, pubkeyfile, strerror(errno));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(*argv, "-in")) {
|
||||||
|
if (--argc < 1) goto bad;
|
||||||
|
infile = *(++argv);
|
||||||
|
if (!(infp = fopen(infile, "rb"))) {
|
||||||
|
fprintf(stderr, "%s: open '%s' failure: %s\n", prog, infile, strerror(errno));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(*argv, "-sig")) {
|
||||||
|
if (--argc < 1) goto bad;
|
||||||
|
sigfile = *(++argv);
|
||||||
|
if (!(sigfp = fopen(sigfile, "rb"))) {
|
||||||
|
fprintf(stderr, "%s: open '%s' failure: %s\n", prog, sigfile, strerror(errno));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} else if (!strcmp(*argv, "-verbose")) {
|
||||||
|
verbose = 1;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||||
|
goto end;
|
||||||
|
bad:
|
||||||
|
fprintf(stderr, "%s: `%s` option value missing\n", prog, *argv);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pubkeyfile) {
|
||||||
|
fprintf(stderr, "%s: `-key` option required\n", prog);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (!sigfile) {
|
||||||
|
fprintf(stderr, "%s: `-sig` option required\n", prog);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fread(pubkeybuf, 1, pubkeylen, pubkeyfp) != pubkeylen) {
|
||||||
|
fprintf(stderr, "%s: read public key failure\n", prog);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (xmss_public_key_from_bytes(&key, cp, pubkeylen) != 1) {
|
||||||
|
error_print();
|
||||||
|
fprintf(stderr, "%s: invalid public key data\n", prog);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (verbose) {
|
||||||
|
xmss_key_print(stderr, 0, 0, "xmss_public_key", &key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read signature even if signature not compatible with the public key
|
||||||
|
if ((siglen = fread(sig, 1, XMSS_SIGNATURE_MAX_SIZE, sigfp)) <= 0) {
|
||||||
|
fprintf(stderr, "%s: read signature failure\n", prog);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (verbose) {
|
||||||
|
xmss_signature_print(stderr, 0, 0, "xmss_signature", sig, siglen);
|
||||||
|
}
|
||||||
|
if (xmss_verify_init(&ctx, &key, sig, siglen) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint8_t buf[1024];
|
||||||
|
size_t len = fread(buf, 1, sizeof(buf), infp);
|
||||||
|
if (len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (xmss_verify_update(&ctx, buf, len) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((vr = xmss_verify_finish(&ctx, &key, sig, siglen)) < 0) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "verify : %s\n", vr == 1 ? "success" : "failure");
|
||||||
|
if (vr == 1) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (pubkeyfp) fclose(pubkeyfp);
|
||||||
|
if (infp && infp != stdin) fclose(infp);
|
||||||
|
if (sigfp) fclose(sigfp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user