mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Add SPHINCS+
This commit is contained in:
184
include/gmssl/sphincs.h
Normal file
184
include/gmssl/sphincs.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2014-2026 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_SPHINCS_H
|
||||
#define GMSSL_SPHINCS_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
|
||||
|
||||
|
||||
#if defined(ENABLE_SPHINCS_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_BLOCK_SIZE SHA256_BLOCK_SIZE
|
||||
#else
|
||||
# define HASH256_CTX SM3_CTX
|
||||
# define hash256_init sm3_init
|
||||
# define hash256_update sm3_update
|
||||
# define hash256_finish sm3_finish
|
||||
# define HASH256_BLOCK_SIZE SM3_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
/*
|
||||
In order to make keeping track of the types easier throughout the pseudo-code in the rest of
|
||||
this document, we refer to them respectively using the constants WOTS_HASH, WOTS_PK, TREE,
|
||||
FORS_TREE, FORS_ROOTS, WOTS_PRF, and FORS_PRF.
|
||||
*/
|
||||
|
||||
enum {
|
||||
SPHINCS_ADRS_TYPE_WOTS_PRF = 0,
|
||||
SPHINCS_ADRS_TYPE_WOTS_PK = 1,
|
||||
SPHINCS_ADRS_TYPE_HASHTREE = 2,
|
||||
SPHINCS_ADRS_TYPE_FORS_TREE = 3,
|
||||
SPHINCS_ADRS_TYPE_FORS_ROOT = 4,
|
||||
SPHINCS_ADRS_TYPE_WOTS_KEYGEN = 5,
|
||||
SPHINCS_ADRS_TYPE_FORS_KEYGEN = 6,
|
||||
};
|
||||
|
||||
typedef uint8_t sphincs_adrs_t[32];
|
||||
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 0
|
||||
uint32_t keypair_address;
|
||||
uint32_t chain_address;
|
||||
uint32_t hash_address;
|
||||
} SPHINCS_ADRS_WOTS_HASH;
|
||||
|
||||
void sphincs_adrs_copy_layer_address(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_copy_tree_address(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_copy_type(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_copy_keypair_address(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_copy_chain_address(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_copy_hash_address(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
|
||||
void sphincs_adrs_set_layer_address(sphincs_adrs_t adrs, const uint32_t address);
|
||||
void sphincs_adrs_set_tree_address(sphincs_adrs_t adrs, const uint64_t address);
|
||||
void sphincs_adrs_set_type(sphincs_adrs_t adrs, const uint32_t type);
|
||||
void sphincs_adrs_set_keypair_address(sphincs_adrs_t adrs, const uint32_t address);
|
||||
void sphincs_adrs_set_chain_address(sphincs_adrs_t adrs, const uint32_t address);
|
||||
void sphincs_adrs_set_hash_address(sphincs_adrs_t adrs, const uint32_t address);
|
||||
|
||||
// 所有的padding都在最后,是否意味着可以不用padding?
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 1
|
||||
uint32_t keypair_address;
|
||||
uint32_t padding[3]; // = {0,0,0}
|
||||
} SPHINCS_ADRS_WOTS_PK_COMP;
|
||||
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 2
|
||||
uint32_t padding; // = 0
|
||||
uint32_t tree_height;
|
||||
uint32_t tree_index;
|
||||
} SPHINCS_ADRS_HASHTREE;
|
||||
|
||||
void sphincs_adrs_copy_tree_height(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_copy_tree_index(sphincs_adrs_t dst, const sphincs_adrs_t src);
|
||||
void sphincs_adrs_set_tree_height(sphincs_adrs_t adrs, uint32_t height);
|
||||
void sphincs_adrs_set_tree_index(sphincs_adrs_t adrs, uint32_t index);
|
||||
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 3
|
||||
uint32_t keypair_address;
|
||||
uint32_t tree_height;
|
||||
uint32_t tree_index;
|
||||
} SPHINCS_ADRS_FORS_TREE;
|
||||
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 4
|
||||
uint32_t keypair_address;
|
||||
uint32_t padding[2]; // = {0,0}
|
||||
} SPHINCS_ADRS_FORS_ROOT;
|
||||
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 5
|
||||
uint32_t keypair_address;
|
||||
uint32_t chain_address;
|
||||
uint32_t hash_address; // = 0
|
||||
} SPHINCS_ADRS_WOTS_KEYGEN;
|
||||
|
||||
typedef struct {
|
||||
uint32_t layer_address;
|
||||
uint32_t tree_address[3];
|
||||
uint32_t type; // = 6
|
||||
uint32_t keypair_address;
|
||||
uint32_t tree_height; // = 0
|
||||
uint32_t tree_index;
|
||||
} SPHINCS_ADRS_FORS_KEYGEN;
|
||||
|
||||
typedef uint8_t sphincs_adrsc_t[22];
|
||||
|
||||
void sphincs_adrs_compress(const sphincs_adrs_t adrs, sphincs_adrsc_t adrsc);
|
||||
|
||||
// 这里比较奇怪的是,fors的参数以及哈希值是多少?
|
||||
// 哈希值被分成两部分,一部分用来从hypertree上找到树的地址,一个是用于fors的输入
|
||||
typedef struct {
|
||||
char *name;
|
||||
size_t secret_size; // 这个是n,当sm3/sha256时n==16
|
||||
size_t height;
|
||||
size_t layers;
|
||||
size_t fors_height;
|
||||
size_t fors_trees;
|
||||
int winternitz_w;
|
||||
int bitsec;
|
||||
int sec_level;
|
||||
size_t siglen;
|
||||
} SPHINCS_PARAMS;
|
||||
|
||||
// sizeof(sphincs_secret_t) == n, when sm3/sha256, n == 16
|
||||
typedef uint8_t sphincs_secret_t[16];
|
||||
|
||||
|
||||
|
||||
void sphincs_wots_chain(const sphincs_secret_t x,
|
||||
const sphincs_secret_t seed, const sphincs_adrs_t ots_adrs,
|
||||
int start, int steps, sphincs_secret_t y);
|
||||
|
||||
|
||||
typedef sphincs_secret_t sphincs_wots_key_t[35];
|
||||
typedef sphincs_secret_t sphincs_wots_sig_t[35];
|
||||
|
||||
|
||||
void sphincs_wots_derive_sk(const sphincs_secret_t secret,
|
||||
const sphincs_secret_t seed, const sphincs_adrs_t adrs,
|
||||
sphincs_wots_key_t sk);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user