blob: 35a0dd148578653ee5078b48c7219b4bf36550f3 [file] [log] [blame] [edit]
// Copyright 2024 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
#include <openssl/base.h>
#include <stdbool.h>
#include "../bcm_interface.h"
#if defined(__cplusplus)
extern "C" {
#endif
enum slh_dsa_hash_type {
SLH_DSA_HASH_SHA2_256,
SLH_DSA_HASH_SHAKE_256,
};
// Upper bounds for stack allocations across all SLH-DSA parameter sets in
// FIPS 205. These keep the code simple and avoid dynamic allocation while
// still covering larger future parameter sets such as SLH-DSA-SHAKE-256f.
#define SLHDSA_MAX_N 32
#define SLHDSA_MAX_WOTS_LEN 67
#define SLHDSA_MAX_WOTS_BYTES (SLHDSA_MAX_N * SLHDSA_MAX_WOTS_LEN)
#define SLHDSA_MAX_FORS_HEIGHT 17
#define SLHDSA_MAX_FORS_TREES 35
#define SLHDSA_MAX_FORS_BYTES \
((SLHDSA_MAX_FORS_HEIGHT + 1) * SLHDSA_MAX_FORS_TREES * SLHDSA_MAX_N)
#define SLHDSA_MAX_FORS_MSG_BYTES \
((SLHDSA_MAX_FORS_HEIGHT * SLHDSA_MAX_FORS_TREES + 7) / 8)
#define SLHDSA_MAX_TREE_HEIGHT 18
#define SLHDSA_MAX_D 18
#define SLHDSA_MAX_DIGEST_SIZE 64
#define SLHDSA_MAX_HASH_BLOCK_BYTES 168
// Values bound by these limits are assumed to be valid shifts within a
// uint32_t.
static_assert(SLHDSA_MAX_TREE_HEIGHT < 32);
static_assert(SLHDSA_MAX_FORS_HEIGHT < 32);
#define SLHDSA_ADDR_BYTES 32
#define SLHDSA_ADDR_COMPRESSED_BYTES 22
#define SLHDSA_ADDR_COMP_OFFSET_LAYER 0
#define SLHDSA_ADDR_COMP_OFFSET_TREE 1
#define SLHDSA_ADDR_COMP_OFFSET_TYPE 9
#define SLHDSA_ADDR_COMP_OFFSET_KEYPAIR 10
#define SLHDSA_ADDR_COMP_OFFSET_CHAIN 14
#define SLHDSA_ADDR_COMP_OFFSET_TREE_HEIGHT 14
#define SLHDSA_ADDR_COMP_OFFSET_HASH 18
#define SLHDSA_ADDR_COMP_OFFSET_TREE_INDEX 18
#define SLHDSA_ADDR_COMP_ZERO_START 10
#define SLHDSA_ADDR_COMP_ZERO_LEN 12
#define SLHDSA_ADDR_FULL_OFFSET_LAYER 0
#define SLHDSA_ADDR_FULL_OFFSET_TREE 4
#define SLHDSA_ADDR_FULL_OFFSET_TYPE 16
#define SLHDSA_ADDR_FULL_OFFSET_KEYPAIR 20
#define SLHDSA_ADDR_FULL_OFFSET_CHAIN 24
#define SLHDSA_ADDR_FULL_OFFSET_TREE_HEIGHT 24
#define SLHDSA_ADDR_FULL_OFFSET_HASH 28
#define SLHDSA_ADDR_FULL_OFFSET_TREE_INDEX 28
#define SLHDSA_ADDR_FULL_ZERO_START 20
#define SLHDSA_ADDR_FULL_ZERO_LEN 12
typedef struct slh_dsa_config {
uint32_t n;
uint32_t full_height;
uint32_t d;
uint32_t tree_height;
uint32_t fors_height;
uint32_t fors_trees;
uint32_t wots_w;
uint32_t wots_log_w;
uint32_t wots_len1;
uint32_t wots_len2;
uint32_t digest_size;
uint32_t hash_block_bytes;
uint32_t hash_output_bytes;
uint32_t public_key_bytes;
uint32_t private_key_bytes;
uint32_t signature_bytes;
enum slh_dsa_hash_type hash_type;
bool compressed_addresses;
} slh_dsa_config;
static inline uint32_t slhdsa_wots_len(const slh_dsa_config *config) {
return config->wots_len1 + config->wots_len2;
}
static inline uint32_t slhdsa_wots_bytes(const slh_dsa_config *config) {
return config->n * slhdsa_wots_len(config);
}
static inline uint32_t slhdsa_xmss_bytes(const slh_dsa_config *config) {
return slhdsa_wots_bytes(config) + config->n * config->tree_height;
}
static inline uint32_t slhdsa_fors_msg_bytes(const slh_dsa_config *config) {
return (config->fors_height * config->fors_trees + 7) / 8;
}
static inline uint32_t slhdsa_fors_bytes(const slh_dsa_config *config) {
return (config->fors_height + 1) * config->fors_trees * config->n;
}
static inline uint32_t slhdsa_tree_bits(const slh_dsa_config *config) {
return config->tree_height * (config->d - 1);
}
static inline uint32_t slhdsa_tree_bytes(const slh_dsa_config *config) {
return (slhdsa_tree_bits(config) + 7) / 8;
}
static inline uint32_t slhdsa_leaf_bits(const slh_dsa_config *config) {
return config->tree_height;
}
static inline uint32_t slhdsa_leaf_bytes(const slh_dsa_config *config) {
return (slhdsa_leaf_bits(config) + 7) / 8;
}
static const slh_dsa_config kSLHDSAConfigSHA2_128s = {
/*n=*/BCM_SLHDSA_SHA2_128S_N,
/*full_height=*/63,
/*d=*/7,
/*tree_height=*/9,
/*fors_height=*/12,
/*fors_trees=*/14,
/*wots_w=*/16,
/*wots_log_w=*/4,
/*wots_len1=*/32,
/*wots_len2=*/3,
/*digest_size=*/30,
/*hash_block_bytes=*/64,
/*hash_output_bytes=*/32,
/*public_key_bytes=*/BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES,
/*private_key_bytes=*/BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES,
/*signature_bytes=*/BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES,
/*hash_type=*/SLH_DSA_HASH_SHA2_256,
/*compressed_addresses=*/true,
};
static const slh_dsa_config kSLHDSAConfigSHAKE_256f = {
/*n=*/BCM_SLHDSA_SHAKE_256F_N,
/*full_height=*/68,
/*d=*/17,
/*tree_height=*/4,
/*fors_height=*/9,
/*fors_trees=*/35,
/*wots_w=*/16,
/*wots_log_w=*/4,
/*wots_len1=*/64,
/*wots_len2=*/3,
/*digest_size=*/49,
/*hash_block_bytes=*/136,
/*hash_output_bytes=*/32,
/*public_key_bytes=*/BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES,
/*private_key_bytes=*/BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES,
/*signature_bytes=*/BCM_SLHDSA_SHAKE_256F_SIGNATURE_BYTES,
/*hash_type=*/SLH_DSA_HASH_SHAKE_256,
/*compressed_addresses=*/false,
};
#if defined(__cplusplus)
} // extern C
#endif
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H