update main-with-bazel from master branch
This commit is contained in:
+11
-11
@@ -83,6 +83,11 @@ fips_fragments = [
|
||||
"src/crypto/fipsmodule/sha/sha1.cc.inc",
|
||||
"src/crypto/fipsmodule/sha/sha256.cc.inc",
|
||||
"src/crypto/fipsmodule/sha/sha512.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/fors.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/merkle.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/thash.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/wots.cc.inc",
|
||||
"src/crypto/fipsmodule/tls/kdf.cc.inc",
|
||||
]
|
||||
|
||||
@@ -258,6 +263,12 @@ crypto_internal_headers = [
|
||||
"src/crypto/fipsmodule/rsa/internal.h",
|
||||
"src/crypto/fipsmodule/service_indicator/internal.h",
|
||||
"src/crypto/fipsmodule/sha/internal.h",
|
||||
"src/crypto/fipsmodule/slhdsa/address.h",
|
||||
"src/crypto/fipsmodule/slhdsa/fors.h",
|
||||
"src/crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"src/crypto/fipsmodule/slhdsa/params.h",
|
||||
"src/crypto/fipsmodule/slhdsa/thash.h",
|
||||
"src/crypto/fipsmodule/slhdsa/wots.h",
|
||||
"src/crypto/fipsmodule/tls/internal.h",
|
||||
"src/crypto/hrss/internal.h",
|
||||
"src/crypto/internal.h",
|
||||
@@ -272,13 +283,6 @@ crypto_internal_headers = [
|
||||
"src/crypto/rand_extra/getrandom_fillin.h",
|
||||
"src/crypto/rand_extra/sysrand_internal.h",
|
||||
"src/crypto/rsa_extra/internal.h",
|
||||
"src/crypto/slhdsa/address.h",
|
||||
"src/crypto/slhdsa/fors.h",
|
||||
"src/crypto/slhdsa/internal.h",
|
||||
"src/crypto/slhdsa/merkle.h",
|
||||
"src/crypto/slhdsa/params.h",
|
||||
"src/crypto/slhdsa/thash.h",
|
||||
"src/crypto/slhdsa/wots.h",
|
||||
"src/crypto/trust_token/internal.h",
|
||||
"src/crypto/x509/ext_dat.h",
|
||||
"src/crypto/x509/internal.h",
|
||||
@@ -449,11 +453,7 @@ crypto_sources = [
|
||||
"src/crypto/sha/sha256.cc",
|
||||
"src/crypto/sha/sha512.cc",
|
||||
"src/crypto/siphash/siphash.cc",
|
||||
"src/crypto/slhdsa/fors.cc",
|
||||
"src/crypto/slhdsa/merkle.cc",
|
||||
"src/crypto/slhdsa/slhdsa.cc",
|
||||
"src/crypto/slhdsa/thash.cc",
|
||||
"src/crypto/slhdsa/wots.cc",
|
||||
"src/crypto/stack/stack.cc",
|
||||
"src/crypto/thread.cc",
|
||||
"src/crypto/thread_none.cc",
|
||||
|
||||
@@ -37,6 +37,12 @@ test_support_sources = [
|
||||
"src/crypto/fipsmodule/rsa/internal.h",
|
||||
"src/crypto/fipsmodule/service_indicator/internal.h",
|
||||
"src/crypto/fipsmodule/sha/internal.h",
|
||||
"src/crypto/fipsmodule/slhdsa/address.h",
|
||||
"src/crypto/fipsmodule/slhdsa/fors.h",
|
||||
"src/crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"src/crypto/fipsmodule/slhdsa/params.h",
|
||||
"src/crypto/fipsmodule/slhdsa/thash.h",
|
||||
"src/crypto/fipsmodule/slhdsa/wots.h",
|
||||
"src/crypto/fipsmodule/tls/internal.h",
|
||||
"src/crypto/hrss/internal.h",
|
||||
"src/crypto/internal.h",
|
||||
@@ -51,13 +57,6 @@ test_support_sources = [
|
||||
"src/crypto/rand_extra/getrandom_fillin.h",
|
||||
"src/crypto/rand_extra/sysrand_internal.h",
|
||||
"src/crypto/rsa_extra/internal.h",
|
||||
"src/crypto/slhdsa/address.h",
|
||||
"src/crypto/slhdsa/fors.h",
|
||||
"src/crypto/slhdsa/internal.h",
|
||||
"src/crypto/slhdsa/merkle.h",
|
||||
"src/crypto/slhdsa/params.h",
|
||||
"src/crypto/slhdsa/thash.h",
|
||||
"src/crypto/slhdsa/wots.h",
|
||||
"src/crypto/test/abi_test.cc",
|
||||
"src/crypto/test/abi_test.h",
|
||||
"src/crypto/test/file_test.cc",
|
||||
|
||||
@@ -420,11 +420,7 @@ add_library(
|
||||
src/crypto/sha/sha256.cc
|
||||
src/crypto/sha/sha512.cc
|
||||
src/crypto/siphash/siphash.cc
|
||||
src/crypto/slhdsa/fors.cc
|
||||
src/crypto/slhdsa/merkle.cc
|
||||
src/crypto/slhdsa/slhdsa.cc
|
||||
src/crypto/slhdsa/thash.cc
|
||||
src/crypto/slhdsa/wots.cc
|
||||
src/crypto/stack/stack.cc
|
||||
src/crypto/thread.cc
|
||||
src/crypto/thread_none.cc
|
||||
|
||||
+11
-11
@@ -160,11 +160,7 @@
|
||||
"src/crypto/sha/sha256.cc",
|
||||
"src/crypto/sha/sha512.cc",
|
||||
"src/crypto/siphash/siphash.cc",
|
||||
"src/crypto/slhdsa/fors.cc",
|
||||
"src/crypto/slhdsa/merkle.cc",
|
||||
"src/crypto/slhdsa/slhdsa.cc",
|
||||
"src/crypto/slhdsa/thash.cc",
|
||||
"src/crypto/slhdsa/wots.cc",
|
||||
"src/crypto/stack/stack.cc",
|
||||
"src/crypto/thread.cc",
|
||||
"src/crypto/thread_none.cc",
|
||||
@@ -502,6 +498,12 @@
|
||||
"src/crypto/fipsmodule/rsa/internal.h",
|
||||
"src/crypto/fipsmodule/service_indicator/internal.h",
|
||||
"src/crypto/fipsmodule/sha/internal.h",
|
||||
"src/crypto/fipsmodule/slhdsa/address.h",
|
||||
"src/crypto/fipsmodule/slhdsa/fors.h",
|
||||
"src/crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"src/crypto/fipsmodule/slhdsa/params.h",
|
||||
"src/crypto/fipsmodule/slhdsa/thash.h",
|
||||
"src/crypto/fipsmodule/slhdsa/wots.h",
|
||||
"src/crypto/fipsmodule/tls/internal.h",
|
||||
"src/crypto/hrss/internal.h",
|
||||
"src/crypto/internal.h",
|
||||
@@ -516,13 +518,6 @@
|
||||
"src/crypto/rand_extra/getrandom_fillin.h",
|
||||
"src/crypto/rand_extra/sysrand_internal.h",
|
||||
"src/crypto/rsa_extra/internal.h",
|
||||
"src/crypto/slhdsa/address.h",
|
||||
"src/crypto/slhdsa/fors.h",
|
||||
"src/crypto/slhdsa/internal.h",
|
||||
"src/crypto/slhdsa/merkle.h",
|
||||
"src/crypto/slhdsa/params.h",
|
||||
"src/crypto/slhdsa/thash.h",
|
||||
"src/crypto/slhdsa/wots.h",
|
||||
"src/crypto/trust_token/internal.h",
|
||||
"src/crypto/x509/ext_dat.h",
|
||||
"src/crypto/x509/internal.h",
|
||||
@@ -976,6 +971,11 @@
|
||||
"src/crypto/fipsmodule/sha/sha1.cc.inc",
|
||||
"src/crypto/fipsmodule/sha/sha256.cc.inc",
|
||||
"src/crypto/fipsmodule/sha/sha512.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/fors.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/merkle.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/thash.cc.inc",
|
||||
"src/crypto/fipsmodule/slhdsa/wots.cc.inc",
|
||||
"src/crypto/fipsmodule/tls/kdf.cc.inc"
|
||||
],
|
||||
"fuzz": [
|
||||
|
||||
+12
-12
@@ -90,6 +90,11 @@
|
||||
"crypto/fipsmodule/sha/sha1.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha256.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha512.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/fors.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/thash.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/wots.cc.inc",
|
||||
"crypto/fipsmodule/tls/kdf.cc.inc"
|
||||
],
|
||||
"asm": [
|
||||
@@ -305,15 +310,11 @@
|
||||
"crypto/rsa_extra/rsa_crypt.cc",
|
||||
"crypto/rsa_extra/rsa_extra.cc",
|
||||
"crypto/rsa_extra/rsa_print.cc",
|
||||
"crypto/slhdsa/slhdsa.cc",
|
||||
"crypto/sha/sha1.cc",
|
||||
"crypto/sha/sha256.cc",
|
||||
"crypto/sha/sha512.cc",
|
||||
"crypto/siphash/siphash.cc",
|
||||
"crypto/slhdsa/fors.cc",
|
||||
"crypto/slhdsa/merkle.cc",
|
||||
"crypto/slhdsa/slhdsa.cc",
|
||||
"crypto/slhdsa/thash.cc",
|
||||
"crypto/slhdsa/wots.cc",
|
||||
"crypto/stack/stack.cc",
|
||||
"crypto/thread.cc",
|
||||
"crypto/thread_none.cc",
|
||||
@@ -518,6 +519,12 @@
|
||||
"crypto/fipsmodule/rsa/internal.h",
|
||||
"crypto/fipsmodule/service_indicator/internal.h",
|
||||
"crypto/fipsmodule/sha/internal.h",
|
||||
"crypto/fipsmodule/slhdsa/address.h",
|
||||
"crypto/fipsmodule/slhdsa/fors.h",
|
||||
"crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"crypto/fipsmodule/slhdsa/params.h",
|
||||
"crypto/fipsmodule/slhdsa/thash.h",
|
||||
"crypto/fipsmodule/slhdsa/wots.h",
|
||||
"crypto/fipsmodule/tls/internal.h",
|
||||
"crypto/hrss/internal.h",
|
||||
"crypto/bcm_support.h",
|
||||
@@ -533,13 +540,6 @@
|
||||
"crypto/rand_extra/getrandom_fillin.h",
|
||||
"crypto/rand_extra/sysrand_internal.h",
|
||||
"crypto/rsa_extra/internal.h",
|
||||
"crypto/slhdsa/address.h",
|
||||
"crypto/slhdsa/fors.h",
|
||||
"crypto/slhdsa/internal.h",
|
||||
"crypto/slhdsa/merkle.h",
|
||||
"crypto/slhdsa/params.h",
|
||||
"crypto/slhdsa/thash.h",
|
||||
"crypto/slhdsa/wots.h",
|
||||
"crypto/trust_token/internal.h",
|
||||
"crypto/x509/ext_dat.h",
|
||||
"crypto/x509/internal.h",
|
||||
|
||||
@@ -108,6 +108,11 @@
|
||||
#include "sha/sha1.cc.inc"
|
||||
#include "sha/sha256.cc.inc"
|
||||
#include "sha/sha512.cc.inc"
|
||||
#include "slhdsa/fors.cc.inc"
|
||||
#include "slhdsa/merkle.cc.inc"
|
||||
#include "slhdsa/slhdsa.cc.inc"
|
||||
#include "slhdsa/thash.cc.inc"
|
||||
#include "slhdsa/wots.cc.inc"
|
||||
#include "tls/kdf.cc.inc"
|
||||
|
||||
|
||||
|
||||
@@ -637,6 +637,91 @@ OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_private_key(
|
||||
CBB *out, const struct BCM_mlkem1024_private_key *private_key);
|
||||
|
||||
|
||||
// SLH-DSA
|
||||
|
||||
// Output length of the hash function.
|
||||
#define BCM_SLHDSA_SHA2_128S_N 16
|
||||
|
||||
// The number of bytes at the beginning of M', the augmented message, before the
|
||||
// context.
|
||||
#define BCM_SLHDSA_M_PRIME_HEADER_LEN 2
|
||||
|
||||
// SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES is the number of bytes in an
|
||||
// SLH-DSA-SHA2-128s public key.
|
||||
#define BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES 32
|
||||
|
||||
// BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES is the number of bytes in an
|
||||
// SLH-DSA-SHA2-128s private key.
|
||||
#define BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES 64
|
||||
|
||||
// BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES is the number of bytes in an
|
||||
// SLH-DSA-SHA2-128s signature.
|
||||
#define BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES 7856
|
||||
|
||||
// SLHDSA_SHA2_128S_generate_key_from_seed generates an SLH-DSA-SHA2-128s key
|
||||
// pair from a 48-byte seed and writes the result to |out_public_key| and
|
||||
// |out_secret_key|.
|
||||
OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed(
|
||||
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]);
|
||||
|
||||
// BCM_slhdsa_sha2_128s_sign_internal acts like |SLHDSA_SHA2_128S_sign| but
|
||||
// accepts an explicit entropy input, which can be PK.seed (bytes 32..48 of
|
||||
// the private key) to generate deterministic signatures. It also takes the
|
||||
// input message in three parts so that the "internal" version of the signing
|
||||
// function, from section 9.2, can be implemented. The |header| argument may be
|
||||
// NULL to omit it.
|
||||
OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_sign_internal(
|
||||
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len,
|
||||
const uint8_t entropy[BCM_SLHDSA_SHA2_128S_N]);
|
||||
|
||||
// BCM_slhdsa_sha2_128s_verify_internal acts like |SLHDSA_SHA2_128S_verify| but
|
||||
// takes the input message in three parts so that the "internal" version of the
|
||||
// verification function, from section 9.3, can be implemented. The |header|
|
||||
// argument may be NULL to omit it.
|
||||
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify_internal(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len);
|
||||
|
||||
OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key(
|
||||
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
|
||||
|
||||
OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_public_from_private(
|
||||
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
|
||||
|
||||
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_sign(
|
||||
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_sign(
|
||||
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_verify(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_ADDRESS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_ADDRESS_H
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../internal.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
@@ -116,4 +116,4 @@ inline uint32_t slhdsa_get_tree_index(uint8_t addr[32]) {
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_ADDRESS_H
|
||||
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_ADDRESS_H
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../internal.h"
|
||||
#include "./address.h"
|
||||
#include "./fors.h"
|
||||
#include "./params.h"
|
||||
@@ -40,9 +40,9 @@ static void fors_base_b(
|
||||
}
|
||||
|
||||
// Implements Algorithm 14: fors_skGen function (page 29)
|
||||
void slhdsa_fors_sk_gen(uint8_t fors_sk[SLHDSA_SHA2_128S_N], uint32_t idx,
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_fors_sk_gen(uint8_t fors_sk[BCM_SLHDSA_SHA2_128S_N], uint32_t idx,
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
uint8_t sk_addr[32];
|
||||
OPENSSL_memcpy(sk_addr, addr, sizeof(sk_addr));
|
||||
@@ -54,27 +54,27 @@ void slhdsa_fors_sk_gen(uint8_t fors_sk[SLHDSA_SHA2_128S_N], uint32_t idx,
|
||||
}
|
||||
|
||||
// Implements Algorithm 15: fors_node function (page 30)
|
||||
void slhdsa_fors_treehash(uint8_t root_node[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_fors_treehash(uint8_t root_node[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint32_t i /*target node index*/,
|
||||
uint32_t z /*target node height*/,
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
BSSL_CHECK(z <= SLHDSA_SHA2_128S_FORS_HEIGHT);
|
||||
BSSL_CHECK(i < (uint32_t)(SLHDSA_SHA2_128S_FORS_TREES *
|
||||
(1 << (SLHDSA_SHA2_128S_FORS_HEIGHT - z))));
|
||||
|
||||
if (z == 0) {
|
||||
uint8_t sk[SLHDSA_SHA2_128S_N];
|
||||
uint8_t sk[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_set_tree_height(addr, 0);
|
||||
slhdsa_set_tree_index(addr, i);
|
||||
slhdsa_fors_sk_gen(sk, i, sk_seed, pk_seed, addr);
|
||||
slhdsa_thash_f(root_node, sk, pk_seed, addr);
|
||||
} else {
|
||||
// Stores left node and right node.
|
||||
uint8_t nodes[2 * SLHDSA_SHA2_128S_N];
|
||||
uint8_t nodes[2 * BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_fors_treehash(nodes, sk_seed, 2 * i, z - 1, pk_seed, addr);
|
||||
slhdsa_fors_treehash(nodes + SLHDSA_SHA2_128S_N, sk_seed, 2 * i + 1, z - 1,
|
||||
slhdsa_fors_treehash(nodes + BCM_SLHDSA_SHA2_128S_N, sk_seed, 2 * i + 1, z - 1,
|
||||
pk_seed, addr);
|
||||
slhdsa_set_tree_height(addr, z);
|
||||
slhdsa_set_tree_index(addr, i);
|
||||
@@ -85,8 +85,8 @@ void slhdsa_fors_treehash(uint8_t root_node[SLHDSA_SHA2_128S_N],
|
||||
// Implements Algorithm 16: fors_sign function (page 31)
|
||||
void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
uint16_t indices[SLHDSA_SHA2_128S_FORS_TREES];
|
||||
|
||||
@@ -97,14 +97,14 @@ void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
|
||||
slhdsa_set_tree_height(addr, 0);
|
||||
// Write the FORS secret key element to the correct position.
|
||||
slhdsa_fors_sk_gen(
|
||||
fors_sig + i * SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1),
|
||||
fors_sig + i * BCM_SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1),
|
||||
i * (1 << SLHDSA_SHA2_128S_FORS_HEIGHT) + indices[i], sk_seed, pk_seed,
|
||||
addr);
|
||||
for (size_t j = 0; j < SLHDSA_SHA2_128S_FORS_HEIGHT; ++j) {
|
||||
size_t s = (indices[i] / (1 << j)) ^ 1;
|
||||
// Write the FORS auth path element to the correct position.
|
||||
slhdsa_fors_treehash(
|
||||
fors_sig + SLHDSA_SHA2_128S_N *
|
||||
fors_sig + BCM_SLHDSA_SHA2_128S_N *
|
||||
(i * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1) + j + 1),
|
||||
sk_seed, i * (1ULL << (SLHDSA_SHA2_128S_FORS_HEIGHT - j)) + s, j,
|
||||
pk_seed, addr);
|
||||
@@ -114,13 +114,13 @@ void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
|
||||
|
||||
// Implements Algorithm 17: fors_pkFromSig function (page 32)
|
||||
void slhdsa_fors_pk_from_sig(
|
||||
uint8_t fors_pk[SLHDSA_SHA2_128S_N],
|
||||
uint8_t fors_pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
|
||||
uint16_t indices[SLHDSA_SHA2_128S_FORS_TREES];
|
||||
uint8_t tmp[2 * SLHDSA_SHA2_128S_N];
|
||||
uint8_t roots[SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_N];
|
||||
uint8_t tmp[2 * BCM_SLHDSA_SHA2_128S_N];
|
||||
uint8_t roots[SLHDSA_SHA2_128S_FORS_TREES * BCM_SLHDSA_SHA2_128S_N];
|
||||
|
||||
// Derive FORS indices compatible with the NIST changes.
|
||||
fors_base_b(indices, message);
|
||||
@@ -128,11 +128,11 @@ void slhdsa_fors_pk_from_sig(
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_FORS_TREES; ++i) {
|
||||
// Pointer to current sk and authentication path
|
||||
const uint8_t *sk =
|
||||
fors_sig + i * SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1);
|
||||
fors_sig + i * BCM_SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1);
|
||||
const uint8_t *auth =
|
||||
fors_sig + i * SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1) +
|
||||
SLHDSA_SHA2_128S_N;
|
||||
uint8_t nodes[2 * SLHDSA_SHA2_128S_N];
|
||||
fors_sig + i * BCM_SLHDSA_SHA2_128S_N * (SLHDSA_SHA2_128S_FORS_HEIGHT + 1) +
|
||||
BCM_SLHDSA_SHA2_128S_N;
|
||||
uint8_t nodes[2 * BCM_SLHDSA_SHA2_128S_N];
|
||||
|
||||
slhdsa_set_tree_height(addr, 0);
|
||||
slhdsa_set_tree_index(
|
||||
@@ -146,19 +146,19 @@ void slhdsa_fors_pk_from_sig(
|
||||
// Even node
|
||||
if (((indices[i] / (1 << j)) % 2) == 0) {
|
||||
slhdsa_set_tree_index(addr, slhdsa_get_tree_index(addr) / 2);
|
||||
OPENSSL_memcpy(tmp, nodes, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, auth + j * SLHDSA_SHA2_128S_N,
|
||||
SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(nodes + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
OPENSSL_memcpy(tmp, nodes, BCM_SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, auth + j * BCM_SLHDSA_SHA2_128S_N,
|
||||
BCM_SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(nodes + BCM_SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
} else {
|
||||
slhdsa_set_tree_index(addr, (slhdsa_get_tree_index(addr) - 1) / 2);
|
||||
OPENSSL_memcpy(tmp, auth + j * SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, nodes, SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(nodes + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
OPENSSL_memcpy(tmp, auth + j * BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, nodes, BCM_SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(nodes + BCM_SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
}
|
||||
OPENSSL_memcpy(nodes, nodes + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(nodes, nodes + BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
OPENSSL_memcpy(roots + i * SLHDSA_SHA2_128S_N, nodes, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(roots + i * BCM_SLHDSA_SHA2_128S_N, nodes, BCM_SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
|
||||
uint8_t forspk_addr[32];
|
||||
@@ -12,8 +12,8 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_FORS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_FORS_H
|
||||
|
||||
#include "./params.h"
|
||||
|
||||
@@ -23,36 +23,36 @@ extern "C" {
|
||||
|
||||
|
||||
// Implements Algorithm 14: fors_skGen function (page 29)
|
||||
void slhdsa_fors_sk_gen(uint8_t fors_sk[SLHDSA_SHA2_128S_N], uint32_t idx,
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_fors_sk_gen(uint8_t fors_sk[BCM_SLHDSA_SHA2_128S_N], uint32_t idx,
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 15: fors_node function (page 30)
|
||||
void slhdsa_fors_treehash(uint8_t root_node[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_fors_treehash(uint8_t root_node[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint32_t i /*target node index*/,
|
||||
uint32_t z /*target node height*/,
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 16: fors_sign function (page 31)
|
||||
void slhdsa_fors_sign(uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 17: fors_pkFromSig function (page 32)
|
||||
void slhdsa_fors_pk_from_sig(
|
||||
uint8_t fors_pk[SLHDSA_SHA2_128S_N],
|
||||
uint8_t fors_pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t fors_sig[SLHDSA_SHA2_128S_FORS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_FORS_MSG_BYTES],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]);
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_FORS_H
|
||||
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_FORS_H
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../internal.h"
|
||||
#include "./address.h"
|
||||
#include "./merkle.h"
|
||||
#include "./params.h"
|
||||
@@ -25,11 +25,11 @@
|
||||
|
||||
|
||||
// Implements Algorithm 9: xmss_node function (page 23)
|
||||
void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_treehash(uint8_t out_pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint32_t i /*target node index*/,
|
||||
uint32_t z /*target node height*/,
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
BSSL_CHECK(z <= SLHDSA_SHA2_128S_TREE_HEIGHT);
|
||||
BSSL_CHECK(i < (uint32_t)(1 << (SLHDSA_SHA2_128S_TREE_HEIGHT - z)));
|
||||
@@ -40,9 +40,9 @@ void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N],
|
||||
slhdsa_wots_pk_gen(out_pk, sk_seed, pk_seed, addr);
|
||||
} else {
|
||||
// Stores left node and right node.
|
||||
uint8_t nodes[2 * SLHDSA_SHA2_128S_N];
|
||||
uint8_t nodes[2 * BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_treehash(nodes, sk_seed, 2 * i, z - 1, pk_seed, addr);
|
||||
slhdsa_treehash(nodes + SLHDSA_SHA2_128S_N, sk_seed, 2 * i + 1, z - 1,
|
||||
slhdsa_treehash(nodes + BCM_SLHDSA_SHA2_128S_N, sk_seed, 2 * i + 1, z - 1,
|
||||
pk_seed, addr);
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_HASHTREE);
|
||||
slhdsa_set_tree_height(addr, z);
|
||||
@@ -53,14 +53,14 @@ void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N],
|
||||
|
||||
// Implements Algorithm 10: xmss_sign function (page 24)
|
||||
void slhdsa_xmss_sign(uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES],
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N], unsigned int idx,
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N], unsigned int idx,
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
// Build authentication path
|
||||
for (size_t j = 0; j < SLHDSA_SHA2_128S_TREE_HEIGHT; ++j) {
|
||||
unsigned int k = (idx >> j) ^ 1;
|
||||
slhdsa_treehash(sig + SLHDSA_SHA2_128S_WOTS_BYTES + j * SLHDSA_SHA2_128S_N,
|
||||
slhdsa_treehash(sig + SLHDSA_SHA2_128S_WOTS_BYTES + j * BCM_SLHDSA_SHA2_128S_N,
|
||||
sk_seed, k, j, pk_seed, addr);
|
||||
}
|
||||
|
||||
@@ -72,52 +72,52 @@ void slhdsa_xmss_sign(uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES],
|
||||
|
||||
// Implements Algorithm 11: xmss_pkFromSig function (page 25)
|
||||
void slhdsa_xmss_pk_from_sig(
|
||||
uint8_t root[SLHDSA_SHA2_128S_N],
|
||||
uint8_t root[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t xmss_sig[SLHDSA_SHA2_128S_XMSS_BYTES], unsigned int idx,
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
|
||||
// Stores node[0] and node[1] from Algorithm 11
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_WOTS);
|
||||
slhdsa_set_keypair_addr(addr, idx);
|
||||
uint8_t node[2 * SLHDSA_SHA2_128S_N];
|
||||
uint8_t node[2 * BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_wots_pk_from_sig(node, xmss_sig, msg, pk_seed, addr);
|
||||
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_HASHTREE);
|
||||
slhdsa_set_tree_index(addr, idx);
|
||||
|
||||
uint8_t tmp[2 * SLHDSA_SHA2_128S_N];
|
||||
uint8_t tmp[2 * BCM_SLHDSA_SHA2_128S_N];
|
||||
const uint8_t *const auth = xmss_sig + SLHDSA_SHA2_128S_WOTS_BYTES;
|
||||
for (size_t k = 0; k < SLHDSA_SHA2_128S_TREE_HEIGHT; ++k) {
|
||||
slhdsa_set_tree_height(addr, k + 1);
|
||||
if (((idx >> k) & 1) == 0) {
|
||||
slhdsa_set_tree_index(addr, slhdsa_get_tree_index(addr) >> 1);
|
||||
OPENSSL_memcpy(tmp, node, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, auth + k * SLHDSA_SHA2_128S_N,
|
||||
SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(node + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
OPENSSL_memcpy(tmp, node, BCM_SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, auth + k * BCM_SLHDSA_SHA2_128S_N,
|
||||
BCM_SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(node + BCM_SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
} else {
|
||||
slhdsa_set_tree_index(addr, (slhdsa_get_tree_index(addr) - 1) >> 1);
|
||||
OPENSSL_memcpy(tmp, auth + k * SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + SLHDSA_SHA2_128S_N, node, SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(node + SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
OPENSSL_memcpy(tmp, auth + k * BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(tmp + BCM_SLHDSA_SHA2_128S_N, node, BCM_SLHDSA_SHA2_128S_N);
|
||||
slhdsa_thash_h(node + BCM_SLHDSA_SHA2_128S_N, tmp, pk_seed, addr);
|
||||
}
|
||||
OPENSSL_memcpy(node, node + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(node, node + BCM_SLHDSA_SHA2_128S_N, BCM_SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
OPENSSL_memcpy(root, node, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(root, node, BCM_SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
|
||||
// Implements Algorithm 12: ht_sign function (page 27)
|
||||
void slhdsa_ht_sign(
|
||||
uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES * SLHDSA_SHA2_128S_D],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N]) {
|
||||
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N]) {
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_tree_addr(addr, idx_tree);
|
||||
|
||||
// Layer 0
|
||||
slhdsa_xmss_sign(sig, message, idx_leaf, sk_seed, pk_seed, addr);
|
||||
uint8_t root[SLHDSA_SHA2_128S_N];
|
||||
uint8_t root[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_xmss_pk_from_sig(root, sig, idx_leaf, message, pk_seed, addr);
|
||||
sig += SLHDSA_SHA2_128S_XMSS_BYTES;
|
||||
|
||||
@@ -139,13 +139,13 @@ void slhdsa_ht_sign(
|
||||
// Implements Algorithm 13: ht_verify function (page 28)
|
||||
int slhdsa_ht_verify(
|
||||
const uint8_t sig[SLHDSA_SHA2_128S_D * SLHDSA_SHA2_128S_XMSS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t pk_root[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N]) {
|
||||
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N]) {
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_tree_addr(addr, idx_tree);
|
||||
|
||||
uint8_t node[SLHDSA_SHA2_128S_N];
|
||||
uint8_t node[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_xmss_pk_from_sig(node, sig, idx_leaf, message, pk_seed, addr);
|
||||
|
||||
for (size_t j = 1; j < SLHDSA_SHA2_128S_D; ++j) {
|
||||
@@ -157,5 +157,5 @@ int slhdsa_ht_verify(
|
||||
slhdsa_xmss_pk_from_sig(node, sig + j * SLHDSA_SHA2_128S_XMSS_BYTES,
|
||||
idx_leaf, node, pk_seed, addr);
|
||||
}
|
||||
return memcmp(node, pk_root, SLHDSA_SHA2_128S_N) == 0;
|
||||
return memcmp(node, pk_root, BCM_SLHDSA_SHA2_128S_N) == 0;
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_MERKLE_H
|
||||
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_MERKLE_H
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
@@ -27,44 +27,44 @@ extern "C" {
|
||||
|
||||
|
||||
// Implements Algorithm 9: xmss_node function (page 23)
|
||||
void slhdsa_treehash(uint8_t out_pk[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_treehash(uint8_t out_pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint32_t i /*target node index*/,
|
||||
uint32_t z /*target node height*/,
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 10: xmss_sign function (page 24)
|
||||
void slhdsa_xmss_sign(uint8_t sig[SLHDSA_SHA2_128S_XMSS_BYTES],
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N], unsigned int idx,
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N], unsigned int idx,
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 11: xmss_pkFromSig function (page 25)
|
||||
void slhdsa_xmss_pk_from_sig(
|
||||
uint8_t root[SLHDSA_SHA2_128S_N],
|
||||
uint8_t root[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t xmss_sig[SLHDSA_SHA2_128S_XMSS_BYTES], unsigned int idx,
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]);
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 12: ht_sign function (page 27)
|
||||
void slhdsa_ht_sign(
|
||||
uint8_t sig[SLHDSA_SHA2_128S_D * SLHDSA_SHA2_128S_XMSS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N]);
|
||||
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N]);
|
||||
|
||||
// Implements Algorithm 13: ht_verify function (page 28)
|
||||
int slhdsa_ht_verify(
|
||||
const uint8_t sig[SLHDSA_SHA2_128S_D * SLHDSA_SHA2_128S_XMSS_BYTES],
|
||||
const uint8_t message[SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t pk_root[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N]);
|
||||
const uint8_t message[BCM_SLHDSA_SHA2_128S_N], uint64_t idx_tree,
|
||||
uint32_t idx_leaf, const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N]);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_MERKLE_H
|
||||
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_MERKLE_H
|
||||
@@ -12,18 +12,16 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
|
||||
|
||||
#include <openssl/base.h>
|
||||
#include "../bcm_interface.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Output length of the hash function.
|
||||
#define SLHDSA_SHA2_128S_N 16
|
||||
// Total height of the tree structure.
|
||||
#define SLHDSA_SHA2_128S_FULL_HEIGHT 63
|
||||
// Number of subtree layers.
|
||||
@@ -37,10 +35,7 @@ extern "C" {
|
||||
// Size of a FORS signature
|
||||
#define SLHDSA_SHA2_128S_FORS_BYTES \
|
||||
((SLHDSA_SHA2_128S_FORS_HEIGHT + 1) * SLHDSA_SHA2_128S_FORS_TREES * \
|
||||
SLHDSA_SHA2_128S_N)
|
||||
// The number of bytes at the beginning of M', the augmented message, before the
|
||||
// context.
|
||||
#define SLHDSA_M_PRIME_HEADER_LEN 2
|
||||
BCM_SLHDSA_SHA2_128S_N)
|
||||
|
||||
// Winternitz parameter and derived values
|
||||
#define SLHDSA_SHA2_128S_WOTS_W 16
|
||||
@@ -49,12 +44,12 @@ extern "C" {
|
||||
#define SLHDSA_SHA2_128S_WOTS_LEN2 3
|
||||
#define SLHDSA_SHA2_128S_WOTS_LEN 35
|
||||
#define SLHDSA_SHA2_128S_WOTS_BYTES \
|
||||
(SLHDSA_SHA2_128S_N * SLHDSA_SHA2_128S_WOTS_LEN)
|
||||
(BCM_SLHDSA_SHA2_128S_N * SLHDSA_SHA2_128S_WOTS_LEN)
|
||||
|
||||
// XMSS sizes
|
||||
#define SLHDSA_SHA2_128S_XMSS_BYTES \
|
||||
(SLHDSA_SHA2_128S_WOTS_BYTES + \
|
||||
(SLHDSA_SHA2_128S_N * SLHDSA_SHA2_128S_TREE_HEIGHT))
|
||||
(BCM_SLHDSA_SHA2_128S_N * SLHDSA_SHA2_128S_TREE_HEIGHT))
|
||||
|
||||
// Size of the message digest (NOTE: This is only correct for the SHA-256 params
|
||||
// here)
|
||||
@@ -80,4 +75,4 @@ extern "C" {
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_PARAMS_H
|
||||
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_PARAMS_H
|
||||
@@ -0,0 +1,319 @@
|
||||
/* Copyright 2014 The BoringSSL Authors
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "../../internal.h"
|
||||
#include "../bcm_interface.h"
|
||||
#include "address.h"
|
||||
#include "fors.h"
|
||||
#include "merkle.h"
|
||||
#include "params.h"
|
||||
#include "thash.h"
|
||||
|
||||
|
||||
// The OBJECT IDENTIFIER header is also included in these values, per the spec.
|
||||
static const uint8_t kSHA384OID[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
|
||||
0x65, 0x03, 0x04, 0x02, 0x02};
|
||||
#define MAX_OID_LENGTH 11
|
||||
#define MAX_CONTEXT_LENGTH 255
|
||||
|
||||
bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed(
|
||||
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]) {
|
||||
// Initialize SK.seed || SK.prf || PK.seed from seed.
|
||||
OPENSSL_memcpy(out_secret_key, seed, 3 * BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
// Initialize PK.seed from seed.
|
||||
OPENSSL_memcpy(out_public_key, seed + 2 * BCM_SLHDSA_SHA2_128S_N,
|
||||
BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_layer_addr(addr, SLHDSA_SHA2_128S_D - 1);
|
||||
|
||||
// Set PK.root
|
||||
slhdsa_treehash(out_public_key + BCM_SLHDSA_SHA2_128S_N, out_secret_key, 0,
|
||||
SLHDSA_SHA2_128S_TREE_HEIGHT, out_public_key, addr);
|
||||
OPENSSL_memcpy(out_secret_key + 3 * BCM_SLHDSA_SHA2_128S_N,
|
||||
out_public_key + BCM_SLHDSA_SHA2_128S_N,
|
||||
BCM_SLHDSA_SHA2_128S_N);
|
||||
return bcm_infallible::approved;
|
||||
}
|
||||
|
||||
bcm_infallible BCM_slhdsa_sha2_128s_generate_key(
|
||||
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
|
||||
uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N];
|
||||
RAND_bytes(seed, 3 * BCM_SLHDSA_SHA2_128S_N);
|
||||
BCM_slhdsa_sha2_128s_generate_key_from_seed(out_public_key, out_private_key,
|
||||
seed);
|
||||
return bcm_infallible::approved;
|
||||
}
|
||||
|
||||
bcm_infallible BCM_slhdsa_sha2_128s_public_from_private(
|
||||
uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
|
||||
OPENSSL_memcpy(out_public_key, private_key + 2 * BCM_SLHDSA_SHA2_128S_N,
|
||||
BCM_SLHDSA_SHA2_128S_N * 2);
|
||||
return bcm_infallible::approved;
|
||||
}
|
||||
|
||||
// Note that this overreads by a byte. This is fine in the context that it's
|
||||
// used.
|
||||
static uint64_t load_tree_index(const uint8_t in[8]) {
|
||||
static_assert(SLHDSA_SHA2_128S_TREE_BYTES == 7,
|
||||
"This code needs to be updated");
|
||||
uint64_t index = CRYPTO_load_u64_be(in);
|
||||
index >>= 8;
|
||||
index &= (~(uint64_t)0) >> (64 - SLHDSA_SHA2_128S_TREE_BITS);
|
||||
return index;
|
||||
}
|
||||
|
||||
// Implements Algorithm 22: slh_sign function (Section 10.2.1, page 39)
|
||||
bcm_infallible BCM_slhdsa_sha2_128s_sign_internal(
|
||||
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len,
|
||||
const uint8_t entropy[BCM_SLHDSA_SHA2_128S_N]) {
|
||||
const uint8_t *sk_seed = secret_key;
|
||||
const uint8_t *sk_prf = secret_key + BCM_SLHDSA_SHA2_128S_N;
|
||||
const uint8_t *pk_seed = secret_key + 2 * BCM_SLHDSA_SHA2_128S_N;
|
||||
const uint8_t *pk_root = secret_key + 3 * BCM_SLHDSA_SHA2_128S_N;
|
||||
|
||||
// Derive randomizer R and copy it to signature
|
||||
uint8_t R[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_thash_prfmsg(R, sk_prf, entropy, header, context, context_len, msg,
|
||||
msg_len);
|
||||
OPENSSL_memcpy(out_signature, R, BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
// Compute message digest
|
||||
uint8_t digest[SLHDSA_SHA2_128S_DIGEST_SIZE];
|
||||
slhdsa_thash_hmsg(digest, R, pk_seed, pk_root, header, context, context_len,
|
||||
msg, msg_len);
|
||||
|
||||
uint8_t fors_digest[SLHDSA_SHA2_128S_FORS_MSG_BYTES];
|
||||
OPENSSL_memcpy(fors_digest, digest, SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
|
||||
const uint64_t idx_tree =
|
||||
load_tree_index(digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
uint32_t idx_leaf = CRYPTO_load_u16_be(
|
||||
digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES + SLHDSA_SHA2_128S_TREE_BYTES);
|
||||
idx_leaf &= (~(uint32_t)0) >> (32 - SLHDSA_SHA2_128S_LEAF_BITS);
|
||||
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_tree_addr(addr, idx_tree);
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE);
|
||||
slhdsa_set_keypair_addr(addr, idx_leaf);
|
||||
|
||||
slhdsa_fors_sign(out_signature + BCM_SLHDSA_SHA2_128S_N, fors_digest, sk_seed,
|
||||
pk_seed, addr);
|
||||
|
||||
uint8_t pk_fors[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_fors_pk_from_sig(pk_fors, out_signature + BCM_SLHDSA_SHA2_128S_N,
|
||||
fors_digest, pk_seed, addr);
|
||||
|
||||
slhdsa_ht_sign(
|
||||
out_signature + BCM_SLHDSA_SHA2_128S_N + SLHDSA_SHA2_128S_FORS_BYTES,
|
||||
pk_fors, idx_tree, idx_leaf, sk_seed, pk_seed);
|
||||
return bcm_infallible::approved;
|
||||
}
|
||||
|
||||
bcm_status BCM_slhdsa_sha2_128s_sign(
|
||||
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
// Construct header for M' as specified in Algorithm 22
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 0; // domain separator for pure signing
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
uint8_t entropy[BCM_SLHDSA_SHA2_128S_N];
|
||||
RAND_bytes(entropy, sizeof(entropy));
|
||||
BCM_slhdsa_sha2_128s_sign_internal(out_signature, private_key, M_prime_header,
|
||||
context, context_len, msg, msg_len,
|
||||
entropy);
|
||||
return bcm_status::approved;
|
||||
}
|
||||
|
||||
static int slhdsa_get_context_and_oid(uint8_t *out_context_and_oid,
|
||||
size_t *out_context_and_oid_len,
|
||||
size_t max_out_context_and_oid,
|
||||
const uint8_t *context,
|
||||
size_t context_len, int hash_nid,
|
||||
size_t hashed_msg_len) {
|
||||
const uint8_t *oid;
|
||||
size_t oid_len;
|
||||
size_t expected_hash_len;
|
||||
switch (hash_nid) {
|
||||
// The SLH-DSA spec only lists SHA-256 and SHA-512. This function supports
|
||||
// SHA-384, which is non-standard.
|
||||
case NID_sha384:
|
||||
oid = kSHA384OID;
|
||||
oid_len = sizeof(kSHA384OID);
|
||||
static_assert(sizeof(kSHA384OID) <= MAX_OID_LENGTH, "");
|
||||
expected_hash_len = 48;
|
||||
break;
|
||||
// If adding a hash function with a larger `oid_len`, update the size of
|
||||
// `context_and_oid` in the callers.
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hashed_msg_len != expected_hash_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_context_and_oid_len = context_len + oid_len;
|
||||
if (*out_context_and_oid_len > max_out_context_and_oid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_memcpy(out_context_and_oid, context, context_len);
|
||||
OPENSSL_memcpy(out_context_and_oid + context_len, oid, oid_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bcm_status BCM_slhdsa_sha2_128s_prehash_sign(
|
||||
uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
|
||||
const uint8_t *context, size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 1; // domain separator for prehashed signing
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
|
||||
size_t context_and_oid_len;
|
||||
if (!slhdsa_get_context_and_oid(context_and_oid, &context_and_oid_len,
|
||||
sizeof(context_and_oid), context, context_len,
|
||||
hash_nid, hashed_msg_len)) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
uint8_t entropy[BCM_SLHDSA_SHA2_128S_N];
|
||||
RAND_bytes(entropy, sizeof(entropy));
|
||||
BCM_slhdsa_sha2_128s_sign_internal(out_signature, private_key, M_prime_header,
|
||||
context_and_oid, context_and_oid_len,
|
||||
hashed_msg, hashed_msg_len, entropy);
|
||||
return bcm_status::approved;
|
||||
}
|
||||
|
||||
// Implements Algorithm 24: slh_verify function (Section 10.3, page 41)
|
||||
bcm_status BCM_slhdsa_sha2_128s_verify(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
// Construct header for M' as specified in Algorithm 24
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 0; // domain separator for pure verification
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
return BCM_slhdsa_sha2_128s_verify_internal(
|
||||
signature, signature_len, public_key, M_prime_header, context,
|
||||
context_len, msg, msg_len);
|
||||
}
|
||||
|
||||
bcm_status BCM_slhdsa_sha2_128s_prehash_verify(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
|
||||
const uint8_t *context, size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 1; // domain separator for prehashed verification
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
|
||||
size_t context_and_oid_len;
|
||||
if (!slhdsa_get_context_and_oid(context_and_oid, &context_and_oid_len,
|
||||
sizeof(context_and_oid), context, context_len,
|
||||
hash_nid, hashed_msg_len)) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
return BCM_slhdsa_sha2_128s_verify_internal(
|
||||
signature, signature_len, public_key, M_prime_header, context_and_oid,
|
||||
context_and_oid_len, hashed_msg, hashed_msg_len);
|
||||
}
|
||||
|
||||
bcm_status BCM_slhdsa_sha2_128s_verify_internal(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len) {
|
||||
if (signature_len != BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
const uint8_t *pk_seed = public_key;
|
||||
const uint8_t *pk_root = public_key + BCM_SLHDSA_SHA2_128S_N;
|
||||
|
||||
const uint8_t *r = signature;
|
||||
const uint8_t *sig_fors = signature + BCM_SLHDSA_SHA2_128S_N;
|
||||
const uint8_t *sig_ht = sig_fors + SLHDSA_SHA2_128S_FORS_BYTES;
|
||||
|
||||
uint8_t digest[SLHDSA_SHA2_128S_DIGEST_SIZE];
|
||||
slhdsa_thash_hmsg(digest, r, pk_seed, pk_root, header, context, context_len,
|
||||
msg, msg_len);
|
||||
|
||||
uint8_t fors_digest[SLHDSA_SHA2_128S_FORS_MSG_BYTES];
|
||||
OPENSSL_memcpy(fors_digest, digest, SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
|
||||
const uint64_t idx_tree =
|
||||
load_tree_index(digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
uint32_t idx_leaf = CRYPTO_load_u16_be(
|
||||
digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES + SLHDSA_SHA2_128S_TREE_BYTES);
|
||||
idx_leaf &= (~(uint32_t)0) >> (32 - SLHDSA_SHA2_128S_LEAF_BITS);
|
||||
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_tree_addr(addr, idx_tree);
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE);
|
||||
slhdsa_set_keypair_addr(addr, idx_leaf);
|
||||
|
||||
uint8_t pk_fors[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_fors_pk_from_sig(pk_fors, sig_fors, fors_digest, pk_seed, addr);
|
||||
|
||||
if (!slhdsa_ht_verify(sig_ht, pk_fors, idx_tree, idx_leaf, pk_root,
|
||||
pk_seed)) {
|
||||
return bcm_status::failure;
|
||||
}
|
||||
|
||||
return bcm_status::approved;
|
||||
}
|
||||
@@ -19,108 +19,108 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../internal.h"
|
||||
#include "./params.h"
|
||||
#include "./thash.h"
|
||||
|
||||
|
||||
// Internal thash function used by F, H, and T_l (Section 11.2, pages 44-46)
|
||||
static void slhdsa_thash(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
static void slhdsa_thash(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t *input, size_t input_blocks,
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
SHA256_CTX sha256;
|
||||
SHA256_Init(&sha256);
|
||||
|
||||
// Process pubseed with padding to full block.
|
||||
static const uint8_t kZeros[64 - SLHDSA_SHA2_128S_N] = {0};
|
||||
SHA256_Update(&sha256, pk_seed, SLHDSA_SHA2_128S_N);
|
||||
static const uint8_t kZeros[64 - BCM_SLHDSA_SHA2_128S_N] = {0};
|
||||
SHA256_Update(&sha256, pk_seed, BCM_SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha256, kZeros, sizeof(kZeros));
|
||||
SHA256_Update(&sha256, addr, SLHDSA_SHA2_128S_SHA256_ADDR_BYTES);
|
||||
SHA256_Update(&sha256, input, input_blocks * SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha256, input, input_blocks * BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
uint8_t hash[32];
|
||||
SHA256_Final(hash, &sha256);
|
||||
OPENSSL_memcpy(output, hash, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(output, hash, BCM_SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
|
||||
// Implements PRF_msg function (Section 4.1, page 11 and Section 11.2, pages
|
||||
// 44-46)
|
||||
void slhdsa_thash_prfmsg(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_prf[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t entropy[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN],
|
||||
void slhdsa_thash_prfmsg(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_prf[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t entropy[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN],
|
||||
const uint8_t *ctx, size_t ctx_len, const uint8_t *msg,
|
||||
size_t msg_len) {
|
||||
// Compute HMAC-SHA256(sk_prf, entropy || header || ctx || msg). We inline
|
||||
// HMAC to avoid an allocation.
|
||||
uint8_t hmac_key[SHA256_CBLOCK];
|
||||
static_assert(SLHDSA_SHA2_128S_N <= SHA256_CBLOCK,
|
||||
static_assert(BCM_SLHDSA_SHA2_128S_N <= SHA256_CBLOCK,
|
||||
"HMAC key is larger than block size");
|
||||
OPENSSL_memcpy(hmac_key, sk_prf, SLHDSA_SHA2_128S_N);
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; i++) {
|
||||
OPENSSL_memcpy(hmac_key, sk_prf, BCM_SLHDSA_SHA2_128S_N);
|
||||
for (size_t i = 0; i < BCM_SLHDSA_SHA2_128S_N; i++) {
|
||||
hmac_key[i] ^= 0x36;
|
||||
}
|
||||
OPENSSL_memset(hmac_key + SLHDSA_SHA2_128S_N, 0x36,
|
||||
sizeof(hmac_key) - SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memset(hmac_key + BCM_SLHDSA_SHA2_128S_N, 0x36,
|
||||
sizeof(hmac_key) - BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
SHA256_CTX sha_ctx;
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, hmac_key, sizeof(hmac_key));
|
||||
SHA256_Update(&sha_ctx, entropy, SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha_ctx, entropy, BCM_SLHDSA_SHA2_128S_N);
|
||||
if (header) {
|
||||
SHA256_Update(&sha_ctx, header, SLHDSA_M_PRIME_HEADER_LEN);
|
||||
SHA256_Update(&sha_ctx, header, BCM_SLHDSA_M_PRIME_HEADER_LEN);
|
||||
}
|
||||
SHA256_Update(&sha_ctx, ctx, ctx_len);
|
||||
SHA256_Update(&sha_ctx, msg, msg_len);
|
||||
uint8_t hash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_Final(hash, &sha_ctx);
|
||||
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; i++) {
|
||||
for (size_t i = 0; i < BCM_SLHDSA_SHA2_128S_N; i++) {
|
||||
hmac_key[i] ^= 0x36 ^ 0x5c;
|
||||
}
|
||||
OPENSSL_memset(hmac_key + SLHDSA_SHA2_128S_N, 0x5c,
|
||||
sizeof(hmac_key) - SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memset(hmac_key + BCM_SLHDSA_SHA2_128S_N, 0x5c,
|
||||
sizeof(hmac_key) - BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, hmac_key, sizeof(hmac_key));
|
||||
SHA256_Update(&sha_ctx, hash, sizeof(hash));
|
||||
SHA256_Final(hash, &sha_ctx);
|
||||
|
||||
// Truncate to SLHDSA_SHA2_128S_N bytes
|
||||
OPENSSL_memcpy(output, hash, SLHDSA_SHA2_128S_N);
|
||||
// Truncate to BCM_SLHDSA_SHA2_128S_N bytes
|
||||
OPENSSL_memcpy(output, hash, BCM_SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
|
||||
// Implements H_msg function (Section 4.1, page 11 and Section 11.2, pages
|
||||
// 44-46)
|
||||
void slhdsa_thash_hmsg(uint8_t output[SLHDSA_SHA2_128S_DIGEST_SIZE],
|
||||
const uint8_t r[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_root[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN],
|
||||
const uint8_t r[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN],
|
||||
const uint8_t *ctx, size_t ctx_len, const uint8_t *msg,
|
||||
size_t msg_len) {
|
||||
// MGF1-SHA-256(R || PK.seed || SHA-256(R || PK.seed || PK.root || header ||
|
||||
// ctx || M), m) input_buffer stores R || PK_SEED || SHA256(..) || 4-byte
|
||||
// index
|
||||
uint8_t input_buffer[2 * SLHDSA_SHA2_128S_N + 32 + 4] = {0};
|
||||
OPENSSL_memcpy(input_buffer, r, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(input_buffer + SLHDSA_SHA2_128S_N, pk_seed,
|
||||
SLHDSA_SHA2_128S_N);
|
||||
uint8_t input_buffer[2 * BCM_SLHDSA_SHA2_128S_N + 32 + 4] = {0};
|
||||
OPENSSL_memcpy(input_buffer, r, BCM_SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(input_buffer + BCM_SLHDSA_SHA2_128S_N, pk_seed,
|
||||
BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
// Inner hash
|
||||
SHA256_CTX sha_ctx;
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, r, SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha_ctx, pk_seed, SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha_ctx, pk_root, SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha_ctx, r, BCM_SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha_ctx, pk_seed, BCM_SLHDSA_SHA2_128S_N);
|
||||
SHA256_Update(&sha_ctx, pk_root, BCM_SLHDSA_SHA2_128S_N);
|
||||
if (header) {
|
||||
SHA256_Update(&sha_ctx, header, SLHDSA_M_PRIME_HEADER_LEN);
|
||||
SHA256_Update(&sha_ctx, header, BCM_SLHDSA_M_PRIME_HEADER_LEN);
|
||||
}
|
||||
SHA256_Update(&sha_ctx, ctx, ctx_len);
|
||||
SHA256_Update(&sha_ctx, msg, msg_len);
|
||||
// Write directly into the input buffer
|
||||
SHA256_Final(input_buffer + 2 * SLHDSA_SHA2_128S_N, &sha_ctx);
|
||||
SHA256_Final(input_buffer + 2 * BCM_SLHDSA_SHA2_128S_N, &sha_ctx);
|
||||
|
||||
// MGF1-SHA-256
|
||||
uint8_t hash[32];
|
||||
@@ -131,34 +131,34 @@ void slhdsa_thash_hmsg(uint8_t output[SLHDSA_SHA2_128S_DIGEST_SIZE],
|
||||
}
|
||||
|
||||
// Implements PRF function (Section 4.1, page 11 and Section 11.2, pages 44-46)
|
||||
void slhdsa_thash_prf(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_prf(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
slhdsa_thash(output, sk_seed, 1, pk_seed, addr);
|
||||
}
|
||||
|
||||
// Implements T_l function for WOTS+ public key compression (Section 4.1, page
|
||||
// 11 and Section 11.2, pages 44-46)
|
||||
void slhdsa_thash_tl(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_tl(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
slhdsa_thash(output, input, SLHDSA_SHA2_128S_WOTS_LEN, pk_seed, addr);
|
||||
}
|
||||
|
||||
// Implements H function (Section 4.1, page 11 and Section 11.2, pages 44-46)
|
||||
void slhdsa_thash_h(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[2 * SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_h(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[2 * BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
slhdsa_thash(output, input, 2, pk_seed, addr);
|
||||
}
|
||||
|
||||
// Implements F function (Section 4.1, page 11 and Section 11.2, pages 44-46)
|
||||
void slhdsa_thash_f(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_f(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
slhdsa_thash(output, input, 1, pk_seed, addr);
|
||||
}
|
||||
@@ -166,8 +166,8 @@ void slhdsa_thash_f(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
// Implements T_k function for FORS public key compression (Section 4.1, page 11
|
||||
// and Section 11.2, pages 44-46)
|
||||
void slhdsa_thash_tk(
|
||||
uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
|
||||
uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]) {
|
||||
slhdsa_thash(output, input, SLHDSA_SHA2_128S_FORS_TREES, pk_seed, addr);
|
||||
}
|
||||
@@ -12,8 +12,8 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_THASH_H
|
||||
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_THASH_H
|
||||
|
||||
#include "./params.h"
|
||||
|
||||
@@ -25,61 +25,61 @@ extern "C" {
|
||||
// Implements PRF_msg: a pseudo-random function that is used to generate the
|
||||
// randomizer r for the randomized hashing of the message to be signed.
|
||||
// (Section 4.1, page 11)
|
||||
void slhdsa_thash_prfmsg(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_prf[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t opt_rand[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN],
|
||||
void slhdsa_thash_prfmsg(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_prf[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t opt_rand[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN],
|
||||
const uint8_t *ctx, size_t ctx_len, const uint8_t *msg,
|
||||
size_t msg_len);
|
||||
|
||||
// Implements H_msg: a hash function used to generate the digest of the message
|
||||
// to be signed. (Section 4.1, page 11)
|
||||
void slhdsa_thash_hmsg(uint8_t output[SLHDSA_SHA2_128S_DIGEST_SIZE],
|
||||
const uint8_t r[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_root[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN],
|
||||
const uint8_t r[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_root[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN],
|
||||
const uint8_t *ctx, size_t ctx_len, const uint8_t *msg,
|
||||
size_t msg_len);
|
||||
|
||||
// Implements PRF: a pseudo-random function that is used to generate the secret
|
||||
// values in WOTS+ and FORS private keys. (Section 4.1, page 11)
|
||||
void slhdsa_thash_prf(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_prf(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements T_l: a hash function that maps an l*n-byte message to an n-byte
|
||||
// message. Used for WOTS+ public key compression. (Section 4.1, page 11)
|
||||
void slhdsa_thash_tl(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_tl(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements H: a hash function that takes a 2*n-byte message as input and
|
||||
// produces an n-byte output. (Section 4.1, page 11)
|
||||
void slhdsa_thash_h(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[2 * SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_h(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[2 * BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements F: a hash function that takes an n-byte message as input and
|
||||
// produces an n-byte output. (Section 4.1, page 11)
|
||||
void slhdsa_thash_f(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_thash_f(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements T_k: a hash function that maps a k*n-byte message to an n-byte
|
||||
// message. Used for FORS public key compression. (Section 4.1, page 11)
|
||||
void slhdsa_thash_tk(
|
||||
uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[SLHDSA_SHA2_128S_N], uint8_t addr[32]);
|
||||
uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_FORS_TREES * BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pk_seed[BCM_SLHDSA_SHA2_128S_N], uint8_t addr[32]);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_THASH_H
|
||||
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_THASH_H
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../../internal.h"
|
||||
#include "./address.h"
|
||||
#include "./params.h"
|
||||
#include "./thash.h"
|
||||
@@ -26,14 +26,14 @@
|
||||
|
||||
|
||||
// Implements Algorithm 5: chain function, page 18
|
||||
static void chain(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[SLHDSA_SHA2_128S_N], uint32_t start,
|
||||
uint32_t steps, const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
static void chain(uint8_t output[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t input[BCM_SLHDSA_SHA2_128S_N], uint32_t start,
|
||||
uint32_t steps, const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
assert(start < SLHDSA_SHA2_128S_WOTS_W);
|
||||
assert(steps < SLHDSA_SHA2_128S_WOTS_W);
|
||||
|
||||
OPENSSL_memcpy(output, input, SLHDSA_SHA2_128S_N);
|
||||
OPENSSL_memcpy(output, input, BCM_SLHDSA_SHA2_128S_N);
|
||||
|
||||
for (size_t i = start; i < (start + steps) && i < SLHDSA_SHA2_128S_WOTS_W;
|
||||
++i) {
|
||||
@@ -42,13 +42,13 @@ static void chain(uint8_t output[SLHDSA_SHA2_128S_N],
|
||||
}
|
||||
}
|
||||
|
||||
static void slhdsa_wots_do_chain(uint8_t out[SLHDSA_SHA2_128S_N],
|
||||
static void slhdsa_wots_do_chain(uint8_t out[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t sk_addr[32], uint8_t addr[32],
|
||||
uint8_t value,
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint32_t chain_index) {
|
||||
uint8_t tmp_sk[SLHDSA_SHA2_128S_N];
|
||||
uint8_t tmp_sk[BCM_SLHDSA_SHA2_128S_N];
|
||||
slhdsa_set_chain_addr(sk_addr, chain_index);
|
||||
slhdsa_thash_prf(tmp_sk, pub_seed, sk_seed, sk_addr);
|
||||
slhdsa_set_chain_addr(addr, chain_index);
|
||||
@@ -56,9 +56,9 @@ static void slhdsa_wots_do_chain(uint8_t out[SLHDSA_SHA2_128S_N],
|
||||
}
|
||||
|
||||
// Implements Algorithm 6: wots_pkGen function, page 18
|
||||
void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_wots_pk_gen(uint8_t pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
uint8_t wots_pk_addr[32], sk_addr[32];
|
||||
OPENSSL_memcpy(wots_pk_addr, addr, sizeof(wots_pk_addr));
|
||||
@@ -68,7 +68,7 @@ void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
|
||||
uint8_t tmp[SLHDSA_SHA2_128S_WOTS_BYTES];
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_WOTS_LEN; ++i) {
|
||||
slhdsa_wots_do_chain(tmp + i * SLHDSA_SHA2_128S_N, sk_addr, addr,
|
||||
slhdsa_wots_do_chain(tmp + i * BCM_SLHDSA_SHA2_128S_N, sk_addr, addr,
|
||||
SLHDSA_SHA2_128S_WOTS_W - 1, sk_seed, pub_seed, i);
|
||||
}
|
||||
|
||||
@@ -80,14 +80,14 @@ void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
|
||||
// Implements Algorithm 7: wots_sign function, page 20
|
||||
void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
// Compute checksum
|
||||
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, "");
|
||||
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == BCM_SLHDSA_SHA2_128S_N * 2, "");
|
||||
uint16_t csum = 0;
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
|
||||
for (size_t i = 0; i < BCM_SLHDSA_SHA2_128S_N; ++i) {
|
||||
csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] >> 4);
|
||||
csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] & 15);
|
||||
}
|
||||
@@ -99,23 +99,23 @@ void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
slhdsa_copy_keypair_addr(sk_addr, addr);
|
||||
|
||||
uint32_t chain_index = 0;
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
|
||||
for (size_t i = 0; i < BCM_SLHDSA_SHA2_128S_N; ++i) {
|
||||
slhdsa_wots_do_chain(sig, sk_addr, addr, msg[i] >> 4, sk_seed, pub_seed,
|
||||
chain_index++);
|
||||
sig += SLHDSA_SHA2_128S_N;
|
||||
sig += BCM_SLHDSA_SHA2_128S_N;
|
||||
|
||||
slhdsa_wots_do_chain(sig, sk_addr, addr, msg[i] & 15, sk_seed, pub_seed,
|
||||
chain_index++);
|
||||
sig += SLHDSA_SHA2_128S_N;
|
||||
sig += BCM_SLHDSA_SHA2_128S_N;
|
||||
}
|
||||
|
||||
// Include the SLHDSA_SHA2_128S_WOTS_LEN2 checksum values.
|
||||
slhdsa_wots_do_chain(sig, sk_addr, addr, (csum >> 8) & 15, sk_seed, pub_seed,
|
||||
chain_index++);
|
||||
sig += SLHDSA_SHA2_128S_N;
|
||||
sig += BCM_SLHDSA_SHA2_128S_N;
|
||||
slhdsa_wots_do_chain(sig, sk_addr, addr, (csum >> 4) & 15, sk_seed, pub_seed,
|
||||
chain_index++);
|
||||
sig += SLHDSA_SHA2_128S_N;
|
||||
sig += BCM_SLHDSA_SHA2_128S_N;
|
||||
slhdsa_wots_do_chain(sig, sk_addr, addr, csum & 15, sk_seed, pub_seed,
|
||||
chain_index++);
|
||||
}
|
||||
@@ -123,23 +123,23 @@ void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
static void slhdsa_wots_pk_from_sig_do_chain(
|
||||
uint8_t out[SLHDSA_SHA2_128S_WOTS_BYTES], uint8_t addr[32],
|
||||
const uint8_t in[SLHDSA_SHA2_128S_WOTS_BYTES], uint8_t value,
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N], uint32_t chain_index) {
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N], uint32_t chain_index) {
|
||||
slhdsa_set_chain_addr(addr, chain_index);
|
||||
chain(out + chain_index * SLHDSA_SHA2_128S_N,
|
||||
in + chain_index * SLHDSA_SHA2_128S_N, value,
|
||||
chain(out + chain_index * BCM_SLHDSA_SHA2_128S_N,
|
||||
in + chain_index * BCM_SLHDSA_SHA2_128S_N, value,
|
||||
SLHDSA_SHA2_128S_WOTS_W - 1 - value, pub_seed, addr);
|
||||
}
|
||||
|
||||
// Implements Algorithm 8: wots_pkFromSig function, page 21
|
||||
void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_wots_pk_from_sig(uint8_t pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]) {
|
||||
// Compute checksum
|
||||
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, "");
|
||||
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == BCM_SLHDSA_SHA2_128S_N * 2, "");
|
||||
uint16_t csum = 0;
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
|
||||
for (size_t i = 0; i < BCM_SLHDSA_SHA2_128S_N; ++i) {
|
||||
csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] >> 4);
|
||||
csum += SLHDSA_SHA2_128S_WOTS_W - 1 - (msg[i] & 15);
|
||||
}
|
||||
@@ -149,8 +149,8 @@ void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
OPENSSL_memcpy(wots_pk_addr, addr, sizeof(wots_pk_addr));
|
||||
|
||||
uint32_t chain_index = 0;
|
||||
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == SLHDSA_SHA2_128S_N * 2, "");
|
||||
for (size_t i = 0; i < SLHDSA_SHA2_128S_N; ++i) {
|
||||
static_assert(SLHDSA_SHA2_128S_WOTS_LEN1 == BCM_SLHDSA_SHA2_128S_N * 2, "");
|
||||
for (size_t i = 0; i < BCM_SLHDSA_SHA2_128S_N; ++i) {
|
||||
slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, msg[i] >> 4, pub_seed,
|
||||
chain_index++);
|
||||
slhdsa_wots_pk_from_sig_do_chain(tmp, addr, sig, msg[i] & 15, pub_seed,
|
||||
@@ -12,8 +12,8 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_WOTS_H
|
||||
#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_WOTS_H
|
||||
|
||||
#include "./params.h"
|
||||
|
||||
@@ -23,23 +23,23 @@ extern "C" {
|
||||
|
||||
|
||||
// Implements Algorithm 6: wots_pkGen function, page 18
|
||||
void slhdsa_wots_pk_gen(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_wots_pk_gen(uint8_t pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 7: wots_sign function, page 20
|
||||
void slhdsa_wots_sign(uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sk_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
// Implements Algorithm 8: wots_pkFromSig function, page 21
|
||||
void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
void slhdsa_wots_pk_from_sig(uint8_t pk[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t sig[SLHDSA_SHA2_128S_WOTS_BYTES],
|
||||
const uint8_t msg[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[SLHDSA_SHA2_128S_N],
|
||||
const uint8_t msg[BCM_SLHDSA_SHA2_128S_N],
|
||||
const uint8_t pub_seed[BCM_SLHDSA_SHA2_128S_N],
|
||||
uint8_t addr[32]);
|
||||
|
||||
|
||||
@@ -47,4 +47,4 @@ void slhdsa_wots_pk_from_sig(uint8_t pk[SLHDSA_SHA2_128S_N],
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_WOTS_H
|
||||
#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SLHDSA_WOTS_H
|
||||
@@ -135,7 +135,7 @@ static const uint16_t kModRoots[128] = {
|
||||
|
||||
// reduce_once reduces 0 <= x < 2*kPrime, mod kPrime.
|
||||
static uint16_t reduce_once(uint16_t x) {
|
||||
assert(x < 2 * kPrime);
|
||||
declassify_assert(x < 2 * kPrime);
|
||||
const uint16_t subtracted = x - kPrime;
|
||||
uint16_t mask = 0u - (subtracted >> 15);
|
||||
// Although this is a constant-time select, we omit a value barrier here.
|
||||
@@ -153,7 +153,7 @@ static uint16_t reduce_once(uint16_t x) {
|
||||
// constant time reduce x mod kPrime using Barrett reduction. x must be less
|
||||
// than kPrime + 2×kPrime².
|
||||
static uint16_t reduce(uint32_t x) {
|
||||
assert(x < kPrime + 2u * kPrime * kPrime);
|
||||
declassify_assert(x < kPrime + 2u * kPrime * kPrime);
|
||||
uint64_t product = (uint64_t)x * kBarrettMultiplier;
|
||||
uint32_t quotient = (uint32_t)(product >> kBarrettShift);
|
||||
uint32_t remainder = x - quotient * kPrime;
|
||||
@@ -480,7 +480,9 @@ static int scalar_decode(scalar *out, const uint8_t *in, int bits) {
|
||||
element_bits_done += chunk_bits;
|
||||
}
|
||||
|
||||
if (element >= kPrime) {
|
||||
// An element is only out of range in the case of invalid input, in which
|
||||
// case it is okay to leak the comparison.
|
||||
if (constant_time_declassify_int(element >= kPrime)) {
|
||||
return 0;
|
||||
}
|
||||
out->c[i] = element;
|
||||
@@ -528,7 +530,7 @@ static uint16_t compress(uint16_t x, int bits) {
|
||||
// 0 <= remainder <= kHalfPrime round to 0
|
||||
// kHalfPrime < remainder <= kPrime + kHalfPrime round to 1
|
||||
// kPrime + kHalfPrime < remainder < 2 * kPrime round to 2
|
||||
assert(remainder < 2u * kPrime);
|
||||
declassify_assert(remainder < 2u * kPrime);
|
||||
quotient += 1 & constant_time_lt_w(kHalfPrime, remainder);
|
||||
quotient += 1 & constant_time_lt_w(kPrime + kHalfPrime, remainder);
|
||||
return quotient & ((1 << bits) - 1);
|
||||
@@ -617,6 +619,7 @@ void KYBER_generate_key(uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES],
|
||||
struct KYBER_private_key *out_private_key) {
|
||||
uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY];
|
||||
RAND_bytes(entropy, sizeof(entropy));
|
||||
CONSTTIME_SECRET(entropy, sizeof(entropy));
|
||||
KYBER_generate_key_external_entropy(out_encoded_public_key, out_private_key,
|
||||
entropy);
|
||||
}
|
||||
@@ -645,6 +648,8 @@ void KYBER_generate_key_external_entropy(
|
||||
hash_g(hashed, entropy, 32);
|
||||
const uint8_t *const rho = hashed;
|
||||
const uint8_t *const sigma = hashed + 32;
|
||||
// rho is public.
|
||||
CONSTTIME_DECLASSIFY(rho, 32);
|
||||
OPENSSL_memcpy(priv->pub.rho, hashed, sizeof(priv->pub.rho));
|
||||
matrix_expand(&priv->pub.m, rho);
|
||||
uint8_t counter = 0;
|
||||
@@ -655,6 +660,8 @@ void KYBER_generate_key_external_entropy(
|
||||
vector_ntt(&error);
|
||||
matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s);
|
||||
vector_add(&priv->pub.t, &error);
|
||||
// t is part of the public key and thus is public.
|
||||
CONSTTIME_DECLASSIFY(&priv->pub.t, sizeof(priv->pub.t));
|
||||
|
||||
CBB cbb;
|
||||
CBB_init_fixed(&cbb, out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES);
|
||||
@@ -716,6 +723,7 @@ void KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES],
|
||||
const struct KYBER_public_key *public_key) {
|
||||
uint8_t entropy[KYBER_ENCAP_ENTROPY];
|
||||
RAND_bytes(entropy, KYBER_ENCAP_ENTROPY);
|
||||
CONSTTIME_SECRET(entropy, KYBER_ENCAP_ENTROPY);
|
||||
KYBER_encap_external_entropy(out_ciphertext, out_shared_secret, public_key,
|
||||
entropy);
|
||||
}
|
||||
@@ -739,6 +747,8 @@ void KYBER_encap_external_entropy(
|
||||
uint8_t prekey_and_randomness[64];
|
||||
hash_g(prekey_and_randomness, input, sizeof(input));
|
||||
encrypt_cpa(out_ciphertext, pub, entropy, prekey_and_randomness + 32);
|
||||
// The ciphertext is public.
|
||||
CONSTTIME_DECLASSIFY(out_ciphertext, KYBER_CIPHERTEXT_BYTES);
|
||||
hash_h(prekey_and_randomness + 32, out_ciphertext, KYBER_CIPHERTEXT_BYTES);
|
||||
kdf(out_shared_secret, KYBER_SHARED_SECRET_BYTES, prekey_and_randomness,
|
||||
sizeof(prekey_and_randomness));
|
||||
|
||||
@@ -95,17 +95,20 @@ TEST(KyberTest, Basic) {
|
||||
sizeof(first_two_bytes));
|
||||
CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size());
|
||||
ASSERT_TRUE(KYBER_parse_private_key(priv2.get(), &cbs));
|
||||
EXPECT_EQ(Bytes(encoded_private_key),
|
||||
Bytes(Marshal(KYBER_marshal_private_key, priv2.get())));
|
||||
EXPECT_EQ(
|
||||
Bytes(Declassified(encoded_private_key)),
|
||||
Bytes(Declassified((Marshal(KYBER_marshal_private_key, priv2.get())))));
|
||||
|
||||
uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
|
||||
uint8_t shared_secret1[KYBER_SHARED_SECRET_BYTES];
|
||||
uint8_t shared_secret2[KYBER_SHARED_SECRET_BYTES];
|
||||
KYBER_encap(ciphertext, shared_secret1, pub.get());
|
||||
KYBER_decap(shared_secret2, ciphertext, priv.get());
|
||||
EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2));
|
||||
EXPECT_EQ(Bytes(Declassified(shared_secret1)),
|
||||
Bytes(Declassified(shared_secret2)));
|
||||
KYBER_decap(shared_secret2, ciphertext, priv2.get());
|
||||
EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2));
|
||||
EXPECT_EQ(Bytes(Declassified(shared_secret1)),
|
||||
Bytes(Declassified(shared_secret2)));
|
||||
}
|
||||
|
||||
static void KyberFileTest(FileTest *t) {
|
||||
@@ -134,6 +137,7 @@ static void KyberFileTest(FileTest *t) {
|
||||
// The test vectors provide a CTR-DRBG seed which is used to generate the
|
||||
// input entropy.
|
||||
ASSERT_EQ(seed.size(), size_t{CTR_DRBG_ENTROPY_LEN});
|
||||
CONSTTIME_SECRET(seed.data(), seed.size());
|
||||
{
|
||||
bssl::UniquePtr<CTR_DRBG_STATE> state(
|
||||
CTR_DRBG_new(seed.data(), nullptr, 0));
|
||||
@@ -146,8 +150,10 @@ static void KyberFileTest(FileTest *t) {
|
||||
KYBER_ENCAP_ENTROPY, nullptr, 0));
|
||||
}
|
||||
|
||||
EXPECT_EQ(Bytes(gen_key_entropy), Bytes(given_generate_entropy));
|
||||
EXPECT_EQ(Bytes(encap_entropy), Bytes(given_encap_entropy_pre_hash));
|
||||
EXPECT_EQ(Bytes(Declassified(gen_key_entropy)),
|
||||
Bytes(given_generate_entropy));
|
||||
EXPECT_EQ(Bytes(Declassified(encap_entropy)),
|
||||
Bytes(given_encap_entropy_pre_hash));
|
||||
|
||||
BORINGSSL_keccak(encap_entropy, sizeof(encap_entropy), encap_entropy,
|
||||
sizeof(encap_entropy), boringssl_sha3_256);
|
||||
@@ -165,11 +171,14 @@ static void KyberFileTest(FileTest *t) {
|
||||
encap_entropy);
|
||||
KYBER_decap(decapsulated_key, ciphertext, &priv);
|
||||
|
||||
EXPECT_EQ(Bytes(encapsulated_key), Bytes(decapsulated_key));
|
||||
EXPECT_EQ(Bytes(private_key_expected), Bytes(encoded_private_key));
|
||||
EXPECT_EQ(Bytes(Declassified(encapsulated_key)),
|
||||
Bytes(Declassified(decapsulated_key)));
|
||||
EXPECT_EQ(Bytes(private_key_expected),
|
||||
Bytes(Declassified(encoded_private_key)));
|
||||
EXPECT_EQ(Bytes(public_key_expected), Bytes(encoded_public_key));
|
||||
EXPECT_EQ(Bytes(ciphertext_expected), Bytes(ciphertext));
|
||||
EXPECT_EQ(Bytes(shared_secret_expected), Bytes(encapsulated_key));
|
||||
EXPECT_EQ(Bytes(shared_secret_expected),
|
||||
Bytes(Declassified(encapsulated_key)));
|
||||
|
||||
uint8_t corrupted_ciphertext[KYBER_CIPHERTEXT_BYTES];
|
||||
OPENSSL_memcpy(corrupted_ciphertext, ciphertext, KYBER_CIPHERTEXT_BYTES);
|
||||
@@ -179,7 +188,8 @@ static void KyberFileTest(FileTest *t) {
|
||||
// It would be nice to have actual test vectors for the failure case, but the
|
||||
// NIST submission currently does not include those, so we are just testing
|
||||
// for inequality.
|
||||
EXPECT_NE(Bytes(encapsulated_key), Bytes(corrupted_decapsulated_key));
|
||||
EXPECT_NE(Bytes(Declassified(encapsulated_key)),
|
||||
Bytes(Declassified(corrupted_decapsulated_key)));
|
||||
}
|
||||
|
||||
TEST(KyberTest, TestVectors) {
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/* Copyright 2024 The BoringSSL Authors
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_SLHDSA_INTERNAL_H
|
||||
#define OPENSSL_HEADER_CRYPTO_SLHDSA_INTERNAL_H
|
||||
|
||||
#include <openssl/slhdsa.h>
|
||||
|
||||
#include "params.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// SLHDSA_SHA2_128S_generate_key_from_seed generates an SLH-DSA-SHA2-128s key
|
||||
// pair from a 48-byte seed and writes the result to |out_public_key| and
|
||||
// |out_secret_key|.
|
||||
OPENSSL_EXPORT void SLHDSA_SHA2_128S_generate_key_from_seed(
|
||||
uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t seed[3 * SLHDSA_SHA2_128S_N]);
|
||||
|
||||
// SLHDSA_SHA2_128S_sign_internal acts like |SLHDSA_SHA2_128S_sign| but
|
||||
// accepts an explicit entropy input, which can be PK.seed (bytes 32..48 of
|
||||
// the private key) to generate deterministic signatures. It also takes the
|
||||
// input message in three parts so that the "internal" version of the signing
|
||||
// function, from section 9.2, can be implemented. The |header| argument may be
|
||||
// NULL to omit it.
|
||||
OPENSSL_EXPORT void SLHDSA_SHA2_128S_sign_internal(
|
||||
uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len,
|
||||
const uint8_t entropy[SLHDSA_SHA2_128S_N]);
|
||||
|
||||
// SLHDSA_SHA2_128S_verify_internal acts like |SLHDSA_SHA2_128S_verify| but
|
||||
// takes the input message in three parts so that the "internal" version of the
|
||||
// verification function, from section 9.3, can be implemented. The |header|
|
||||
// argument may be NULL to omit it.
|
||||
OPENSSL_EXPORT int SLHDSA_SHA2_128S_verify_internal(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_SLHDSA_INTERNAL_H
|
||||
+31
-251
@@ -14,122 +14,31 @@
|
||||
|
||||
#include <openssl/slhdsa.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "address.h"
|
||||
#include "fors.h"
|
||||
#include "internal.h"
|
||||
#include "merkle.h"
|
||||
#include "params.h"
|
||||
#include "thash.h"
|
||||
#include "../fipsmodule/bcm_interface.h"
|
||||
|
||||
|
||||
// The OBJECT IDENTIFIER header is also included in these values, per the spec.
|
||||
static const uint8_t kSHA384OID[] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
|
||||
0x65, 0x03, 0x04, 0x02, 0x02};
|
||||
#define MAX_OID_LENGTH 11
|
||||
#define MAX_CONTEXT_LENGTH 255
|
||||
|
||||
void SLHDSA_SHA2_128S_generate_key_from_seed(
|
||||
uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t seed[3 * SLHDSA_SHA2_128S_N]) {
|
||||
// Initialize SK.seed || SK.prf || PK.seed from seed.
|
||||
OPENSSL_memcpy(out_secret_key, seed, 3 * SLHDSA_SHA2_128S_N);
|
||||
|
||||
// Initialize PK.seed from seed.
|
||||
OPENSSL_memcpy(out_public_key, seed + 2 * SLHDSA_SHA2_128S_N,
|
||||
SLHDSA_SHA2_128S_N);
|
||||
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_layer_addr(addr, SLHDSA_SHA2_128S_D - 1);
|
||||
|
||||
// Set PK.root
|
||||
slhdsa_treehash(out_public_key + SLHDSA_SHA2_128S_N, out_secret_key, 0,
|
||||
SLHDSA_SHA2_128S_TREE_HEIGHT, out_public_key, addr);
|
||||
OPENSSL_memcpy(out_secret_key + 3 * SLHDSA_SHA2_128S_N,
|
||||
out_public_key + SLHDSA_SHA2_128S_N, SLHDSA_SHA2_128S_N);
|
||||
}
|
||||
static_assert(SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES ==
|
||||
BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES,
|
||||
"");
|
||||
static_assert(SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES ==
|
||||
BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES,
|
||||
"");
|
||||
static_assert(SLHDSA_SHA2_128S_SIGNATURE_BYTES ==
|
||||
BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES,
|
||||
"");
|
||||
|
||||
void SLHDSA_SHA2_128S_generate_key(
|
||||
uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
uint8_t out_private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
|
||||
uint8_t seed[3 * SLHDSA_SHA2_128S_N];
|
||||
RAND_bytes(seed, 3 * SLHDSA_SHA2_128S_N);
|
||||
SLHDSA_SHA2_128S_generate_key_from_seed(out_public_key, out_private_key,
|
||||
seed);
|
||||
BCM_slhdsa_sha2_128s_generate_key(out_public_key, out_private_key);
|
||||
}
|
||||
|
||||
OPENSSL_EXPORT void SLHDSA_SHA2_128S_public_from_private(
|
||||
void SLHDSA_SHA2_128S_public_from_private(
|
||||
uint8_t out_public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]) {
|
||||
OPENSSL_memcpy(out_public_key, private_key + 2 * SLHDSA_SHA2_128S_N,
|
||||
SLHDSA_SHA2_128S_N * 2);
|
||||
}
|
||||
|
||||
// Note that this overreads by a byte. This is fine in the context that it's
|
||||
// used.
|
||||
static uint64_t load_tree_index(const uint8_t in[8]) {
|
||||
static_assert(SLHDSA_SHA2_128S_TREE_BYTES == 7,
|
||||
"This code needs to be updated");
|
||||
uint64_t index = CRYPTO_load_u64_be(in);
|
||||
index >>= 8;
|
||||
index &= (~(uint64_t)0) >> (64 - SLHDSA_SHA2_128S_TREE_BITS);
|
||||
return index;
|
||||
}
|
||||
|
||||
// Implements Algorithm 22: slh_sign function (Section 10.2.1, page 39)
|
||||
void SLHDSA_SHA2_128S_sign_internal(
|
||||
uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t secret_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len,
|
||||
const uint8_t entropy[SLHDSA_SHA2_128S_N]) {
|
||||
const uint8_t *sk_seed = secret_key;
|
||||
const uint8_t *sk_prf = secret_key + SLHDSA_SHA2_128S_N;
|
||||
const uint8_t *pk_seed = secret_key + 2 * SLHDSA_SHA2_128S_N;
|
||||
const uint8_t *pk_root = secret_key + 3 * SLHDSA_SHA2_128S_N;
|
||||
|
||||
// Derive randomizer R and copy it to signature
|
||||
uint8_t R[SLHDSA_SHA2_128S_N];
|
||||
slhdsa_thash_prfmsg(R, sk_prf, entropy, header, context, context_len, msg,
|
||||
msg_len);
|
||||
OPENSSL_memcpy(out_signature, R, SLHDSA_SHA2_128S_N);
|
||||
|
||||
// Compute message digest
|
||||
uint8_t digest[SLHDSA_SHA2_128S_DIGEST_SIZE];
|
||||
slhdsa_thash_hmsg(digest, R, pk_seed, pk_root, header, context, context_len,
|
||||
msg, msg_len);
|
||||
|
||||
uint8_t fors_digest[SLHDSA_SHA2_128S_FORS_MSG_BYTES];
|
||||
OPENSSL_memcpy(fors_digest, digest, SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
|
||||
const uint64_t idx_tree =
|
||||
load_tree_index(digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
uint32_t idx_leaf = CRYPTO_load_u16_be(
|
||||
digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES + SLHDSA_SHA2_128S_TREE_BYTES);
|
||||
idx_leaf &= (~(uint32_t)0) >> (32 - SLHDSA_SHA2_128S_LEAF_BITS);
|
||||
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_tree_addr(addr, idx_tree);
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE);
|
||||
slhdsa_set_keypair_addr(addr, idx_leaf);
|
||||
|
||||
slhdsa_fors_sign(out_signature + SLHDSA_SHA2_128S_N, fors_digest, sk_seed,
|
||||
pk_seed, addr);
|
||||
|
||||
uint8_t pk_fors[SLHDSA_SHA2_128S_N];
|
||||
slhdsa_fors_pk_from_sig(pk_fors, out_signature + SLHDSA_SHA2_128S_N,
|
||||
fors_digest, pk_seed, addr);
|
||||
|
||||
slhdsa_ht_sign(
|
||||
out_signature + SLHDSA_SHA2_128S_N + SLHDSA_SHA2_128S_FORS_BYTES, pk_fors,
|
||||
idx_tree, idx_leaf, sk_seed, pk_seed);
|
||||
BCM_slhdsa_sha2_128s_public_from_private(out_public_key, private_key);
|
||||
}
|
||||
|
||||
int SLHDSA_SHA2_128S_sign(
|
||||
@@ -137,107 +46,31 @@ int SLHDSA_SHA2_128S_sign(
|
||||
const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Construct header for M' as specified in Algorithm 22
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 0; // domain separator for pure signing
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
uint8_t entropy[SLHDSA_SHA2_128S_N];
|
||||
RAND_bytes(entropy, sizeof(entropy));
|
||||
SLHDSA_SHA2_128S_sign_internal(out_signature, private_key, M_prime_header,
|
||||
context, context_len, msg, msg_len, entropy);
|
||||
return 1;
|
||||
return bcm_success(BCM_slhdsa_sha2_128s_sign(out_signature, private_key, msg,
|
||||
msg_len, context, context_len));
|
||||
}
|
||||
|
||||
static int slhdsa_get_nonstandard_context_and_oid(
|
||||
uint8_t *out_context_and_oid, size_t *out_context_and_oid_len,
|
||||
size_t max_out_context_and_oid, const uint8_t *context, size_t context_len,
|
||||
int hash_nid, size_t hashed_msg_len) {
|
||||
const uint8_t *oid;
|
||||
size_t oid_len;
|
||||
size_t expected_hash_len;
|
||||
switch (hash_nid) {
|
||||
// The SLH-DSA spec only lists SHA-256 and SHA-512. This function supports
|
||||
// SHA-384, which is non-standard.
|
||||
case NID_sha384:
|
||||
oid = kSHA384OID;
|
||||
oid_len = sizeof(kSHA384OID);
|
||||
static_assert(sizeof(kSHA384OID) <= MAX_OID_LENGTH, "");
|
||||
expected_hash_len = 48;
|
||||
break;
|
||||
// If adding a hash function with a larger `oid_len`, update the size of
|
||||
// `context_and_oid` in the callers.
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hashed_msg_len != expected_hash_len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_context_and_oid_len = context_len + oid_len;
|
||||
if (*out_context_and_oid_len > max_out_context_and_oid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPENSSL_memcpy(out_context_and_oid, context, context_len);
|
||||
OPENSSL_memcpy(out_context_and_oid + context_len, oid, oid_len);
|
||||
|
||||
return 1;
|
||||
int SLHDSA_SHA2_128S_verify(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len) {
|
||||
return bcm_success(BCM_slhdsa_sha2_128s_verify(signature, signature_len,
|
||||
public_key, msg, msg_len,
|
||||
context, context_len));
|
||||
}
|
||||
|
||||
|
||||
int SLHDSA_SHA2_128S_prehash_warning_nonstandard_sign(
|
||||
uint8_t out_signature[SLHDSA_SHA2_128S_SIGNATURE_BYTES],
|
||||
const uint8_t private_key[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
|
||||
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
|
||||
const uint8_t *context, size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
if (hash_nid != NID_sha384) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 1; // domain separator for prehashed signing
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
|
||||
size_t context_and_oid_len;
|
||||
if (!slhdsa_get_nonstandard_context_and_oid(
|
||||
context_and_oid, &context_and_oid_len, sizeof(context_and_oid),
|
||||
context, context_len, hash_nid, hashed_msg_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t entropy[SLHDSA_SHA2_128S_N];
|
||||
RAND_bytes(entropy, sizeof(entropy));
|
||||
SLHDSA_SHA2_128S_sign_internal(out_signature, private_key, M_prime_header,
|
||||
context_and_oid, context_and_oid_len,
|
||||
hashed_msg, hashed_msg_len, entropy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Implements Algorithm 24: slh_verify function (Section 10.3, page 41)
|
||||
int SLHDSA_SHA2_128S_verify(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *msg, size_t msg_len, const uint8_t *context,
|
||||
size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Construct header for M' as specified in Algorithm 24
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 0; // domain separator for pure verification
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
return SLHDSA_SHA2_128S_verify_internal(signature, signature_len, public_key,
|
||||
M_prime_header, context, context_len,
|
||||
msg, msg_len);
|
||||
return bcm_success(BCM_slhdsa_sha2_128s_prehash_sign(
|
||||
out_signature, private_key, hashed_msg, hashed_msg_len, hash_nid, context,
|
||||
context_len));
|
||||
}
|
||||
|
||||
int SLHDSA_SHA2_128S_prehash_warning_nonstandard_verify(
|
||||
@@ -245,63 +78,10 @@ int SLHDSA_SHA2_128S_prehash_warning_nonstandard_verify(
|
||||
const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
|
||||
const uint8_t *context, size_t context_len) {
|
||||
if (context_len > MAX_CONTEXT_LENGTH) {
|
||||
if (hash_nid != NID_sha384) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t M_prime_header[2];
|
||||
M_prime_header[0] = 1; // domain separator for prehashed verification
|
||||
M_prime_header[1] = (uint8_t)context_len;
|
||||
|
||||
uint8_t context_and_oid[MAX_CONTEXT_LENGTH + MAX_OID_LENGTH];
|
||||
size_t context_and_oid_len;
|
||||
if (!slhdsa_get_nonstandard_context_and_oid(
|
||||
context_and_oid, &context_and_oid_len, sizeof(context_and_oid),
|
||||
context, context_len, hash_nid, hashed_msg_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SLHDSA_SHA2_128S_verify_internal(
|
||||
signature, signature_len, public_key, M_prime_header, context_and_oid,
|
||||
context_and_oid_len, hashed_msg, hashed_msg_len);
|
||||
}
|
||||
|
||||
int SLHDSA_SHA2_128S_verify_internal(
|
||||
const uint8_t *signature, size_t signature_len,
|
||||
const uint8_t public_key[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
|
||||
const uint8_t header[SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
|
||||
size_t context_len, const uint8_t *msg, size_t msg_len) {
|
||||
if (signature_len != SLHDSA_SHA2_128S_SIGNATURE_BYTES) {
|
||||
return 0;
|
||||
}
|
||||
const uint8_t *pk_seed = public_key;
|
||||
const uint8_t *pk_root = public_key + SLHDSA_SHA2_128S_N;
|
||||
|
||||
const uint8_t *r = signature;
|
||||
const uint8_t *sig_fors = signature + SLHDSA_SHA2_128S_N;
|
||||
const uint8_t *sig_ht = sig_fors + SLHDSA_SHA2_128S_FORS_BYTES;
|
||||
|
||||
uint8_t digest[SLHDSA_SHA2_128S_DIGEST_SIZE];
|
||||
slhdsa_thash_hmsg(digest, r, pk_seed, pk_root, header, context, context_len,
|
||||
msg, msg_len);
|
||||
|
||||
uint8_t fors_digest[SLHDSA_SHA2_128S_FORS_MSG_BYTES];
|
||||
OPENSSL_memcpy(fors_digest, digest, SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
|
||||
const uint64_t idx_tree =
|
||||
load_tree_index(digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES);
|
||||
uint32_t idx_leaf = CRYPTO_load_u16_be(
|
||||
digest + SLHDSA_SHA2_128S_FORS_MSG_BYTES + SLHDSA_SHA2_128S_TREE_BYTES);
|
||||
idx_leaf &= (~(uint32_t)0) >> (32 - SLHDSA_SHA2_128S_LEAF_BITS);
|
||||
|
||||
uint8_t addr[32] = {0};
|
||||
slhdsa_set_tree_addr(addr, idx_tree);
|
||||
slhdsa_set_type(addr, SLHDSA_SHA2_128S_ADDR_TYPE_FORSTREE);
|
||||
slhdsa_set_keypair_addr(addr, idx_leaf);
|
||||
|
||||
uint8_t pk_fors[SLHDSA_SHA2_128S_N];
|
||||
slhdsa_fors_pk_from_sig(pk_fors, sig_fors, fors_digest, pk_seed, addr);
|
||||
|
||||
return slhdsa_ht_verify(sig_ht, pk_fors, idx_tree, idx_leaf, pk_root,
|
||||
pk_seed);
|
||||
return bcm_success(BCM_slhdsa_sha2_128s_prehash_verify(
|
||||
signature, signature_len, public_key, hashed_msg, hashed_msg_len,
|
||||
hash_nid, context, context_len));
|
||||
}
|
||||
|
||||
@@ -22,15 +22,14 @@
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/slhdsa.h>
|
||||
|
||||
#include "../fipsmodule/slhdsa/params.h"
|
||||
#include "../test/file_test.h"
|
||||
#include "../test/test_util.h"
|
||||
#include "internal.h"
|
||||
#include "params.h"
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(SLHDSATest, KeyGeneration) {
|
||||
const uint8_t seed[3 * SLHDSA_SHA2_128S_N] = {0};
|
||||
const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N] = {0};
|
||||
const uint8_t expected_pub[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x6b, 0xd7, 0xe8, 0xe1, 0x98,
|
||||
@@ -47,7 +46,7 @@ TEST(SLHDSATest, KeyGeneration) {
|
||||
|
||||
uint8_t pub[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES];
|
||||
uint8_t priv[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES];
|
||||
SLHDSA_SHA2_128S_generate_key_from_seed(pub, priv, seed);
|
||||
BCM_slhdsa_sha2_128s_generate_key_from_seed(pub, priv, seed);
|
||||
EXPECT_EQ(Bytes(pub), Bytes(expected_pub));
|
||||
EXPECT_EQ(Bytes(priv), Bytes(expected_priv));
|
||||
|
||||
@@ -132,7 +131,7 @@ static void NISTKeyGenerationFileTest(FileTest *t) {
|
||||
|
||||
uint8_t pub[SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES];
|
||||
uint8_t priv[SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES];
|
||||
SLHDSA_SHA2_128S_generate_key_from_seed(pub, priv, seed.data());
|
||||
BCM_slhdsa_sha2_128s_generate_key_from_seed(pub, priv, seed.data());
|
||||
|
||||
EXPECT_EQ(Bytes(pub), Bytes(expected_pub));
|
||||
EXPECT_EQ(Bytes(priv), Bytes(expected_priv));
|
||||
@@ -148,13 +147,13 @@ static void NISTSignatureGenerationFileTest(FileTest *t) {
|
||||
ASSERT_EQ(priv.size(),
|
||||
static_cast<size_t>(SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES));
|
||||
ASSERT_TRUE(t->GetBytes(&entropy, "entropy"));
|
||||
ASSERT_EQ(entropy.size(), static_cast<size_t>(SLHDSA_SHA2_128S_N));
|
||||
ASSERT_EQ(entropy.size(), static_cast<size_t>(BCM_SLHDSA_SHA2_128S_N));
|
||||
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
|
||||
ASSERT_TRUE(t->GetBytes(&expected_sig, "sig"));
|
||||
|
||||
uint8_t sig[SLHDSA_SHA2_128S_SIGNATURE_BYTES];
|
||||
SLHDSA_SHA2_128S_sign_internal(sig, priv.data(), nullptr, nullptr, 0,
|
||||
msg.data(), msg.size(), entropy.data());
|
||||
BCM_slhdsa_sha2_128s_sign_internal(sig, priv.data(), nullptr, nullptr, 0,
|
||||
msg.data(), msg.size(), entropy.data());
|
||||
|
||||
EXPECT_EQ(Bytes(sig), Bytes(expected_sig));
|
||||
}
|
||||
@@ -173,9 +172,9 @@ static void NISTSignatureVerificationFileTest(FileTest *t) {
|
||||
ASSERT_TRUE(t->GetBytes(&sig, "sig"));
|
||||
ASSERT_TRUE(t->GetAttribute(&valid, "valid"));
|
||||
|
||||
int ok = SLHDSA_SHA2_128S_verify_internal(sig.data(), sig.size(), pub.data(),
|
||||
nullptr, nullptr, 0, msg.data(),
|
||||
msg.size());
|
||||
int ok = bcm_success(BCM_slhdsa_sha2_128s_verify_internal(
|
||||
sig.data(), sig.size(), pub.data(), nullptr, nullptr, 0, msg.data(),
|
||||
msg.size()));
|
||||
EXPECT_EQ(ok, valid == "true");
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -93,6 +93,11 @@ bcm_internal_headers = [
|
||||
"crypto/fipsmodule/sha/sha1.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha256.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha512.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/fors.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/thash.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/wots.cc.inc",
|
||||
"crypto/fipsmodule/tls/kdf.cc.inc",
|
||||
]
|
||||
|
||||
@@ -406,11 +411,7 @@ crypto_sources = [
|
||||
"crypto/sha/sha256.cc",
|
||||
"crypto/sha/sha512.cc",
|
||||
"crypto/siphash/siphash.cc",
|
||||
"crypto/slhdsa/fors.cc",
|
||||
"crypto/slhdsa/merkle.cc",
|
||||
"crypto/slhdsa/slhdsa.cc",
|
||||
"crypto/slhdsa/thash.cc",
|
||||
"crypto/slhdsa/wots.cc",
|
||||
"crypto/stack/stack.cc",
|
||||
"crypto/thread.cc",
|
||||
"crypto/thread_none.cc",
|
||||
@@ -619,6 +620,12 @@ crypto_internal_headers = [
|
||||
"crypto/fipsmodule/rsa/internal.h",
|
||||
"crypto/fipsmodule/service_indicator/internal.h",
|
||||
"crypto/fipsmodule/sha/internal.h",
|
||||
"crypto/fipsmodule/slhdsa/address.h",
|
||||
"crypto/fipsmodule/slhdsa/fors.h",
|
||||
"crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"crypto/fipsmodule/slhdsa/params.h",
|
||||
"crypto/fipsmodule/slhdsa/thash.h",
|
||||
"crypto/fipsmodule/slhdsa/wots.h",
|
||||
"crypto/fipsmodule/tls/internal.h",
|
||||
"crypto/hrss/internal.h",
|
||||
"crypto/internal.h",
|
||||
@@ -633,13 +640,6 @@ crypto_internal_headers = [
|
||||
"crypto/rand_extra/getrandom_fillin.h",
|
||||
"crypto/rand_extra/sysrand_internal.h",
|
||||
"crypto/rsa_extra/internal.h",
|
||||
"crypto/slhdsa/address.h",
|
||||
"crypto/slhdsa/fors.h",
|
||||
"crypto/slhdsa/internal.h",
|
||||
"crypto/slhdsa/merkle.h",
|
||||
"crypto/slhdsa/params.h",
|
||||
"crypto/slhdsa/thash.h",
|
||||
"crypto/slhdsa/wots.h",
|
||||
"crypto/trust_token/internal.h",
|
||||
"crypto/x509/ext_dat.h",
|
||||
"crypto/x509/internal.h",
|
||||
|
||||
+11
-11
@@ -97,6 +97,11 @@ set(
|
||||
crypto/fipsmodule/sha/sha1.cc.inc
|
||||
crypto/fipsmodule/sha/sha256.cc.inc
|
||||
crypto/fipsmodule/sha/sha512.cc.inc
|
||||
crypto/fipsmodule/slhdsa/fors.cc.inc
|
||||
crypto/fipsmodule/slhdsa/merkle.cc.inc
|
||||
crypto/fipsmodule/slhdsa/slhdsa.cc.inc
|
||||
crypto/fipsmodule/slhdsa/thash.cc.inc
|
||||
crypto/fipsmodule/slhdsa/wots.cc.inc
|
||||
crypto/fipsmodule/tls/kdf.cc.inc
|
||||
)
|
||||
|
||||
@@ -420,11 +425,7 @@ set(
|
||||
crypto/sha/sha256.cc
|
||||
crypto/sha/sha512.cc
|
||||
crypto/siphash/siphash.cc
|
||||
crypto/slhdsa/fors.cc
|
||||
crypto/slhdsa/merkle.cc
|
||||
crypto/slhdsa/slhdsa.cc
|
||||
crypto/slhdsa/thash.cc
|
||||
crypto/slhdsa/wots.cc
|
||||
crypto/stack/stack.cc
|
||||
crypto/thread.cc
|
||||
crypto/thread_none.cc
|
||||
@@ -637,6 +638,12 @@ set(
|
||||
crypto/fipsmodule/rsa/internal.h
|
||||
crypto/fipsmodule/service_indicator/internal.h
|
||||
crypto/fipsmodule/sha/internal.h
|
||||
crypto/fipsmodule/slhdsa/address.h
|
||||
crypto/fipsmodule/slhdsa/fors.h
|
||||
crypto/fipsmodule/slhdsa/merkle.h
|
||||
crypto/fipsmodule/slhdsa/params.h
|
||||
crypto/fipsmodule/slhdsa/thash.h
|
||||
crypto/fipsmodule/slhdsa/wots.h
|
||||
crypto/fipsmodule/tls/internal.h
|
||||
crypto/hrss/internal.h
|
||||
crypto/internal.h
|
||||
@@ -651,13 +658,6 @@ set(
|
||||
crypto/rand_extra/getrandom_fillin.h
|
||||
crypto/rand_extra/sysrand_internal.h
|
||||
crypto/rsa_extra/internal.h
|
||||
crypto/slhdsa/address.h
|
||||
crypto/slhdsa/fors.h
|
||||
crypto/slhdsa/internal.h
|
||||
crypto/slhdsa/merkle.h
|
||||
crypto/slhdsa/params.h
|
||||
crypto/slhdsa/thash.h
|
||||
crypto/slhdsa/wots.h
|
||||
crypto/trust_token/internal.h
|
||||
crypto/x509/ext_dat.h
|
||||
crypto/x509/internal.h
|
||||
|
||||
+11
-11
@@ -93,6 +93,11 @@ bcm_internal_headers = [
|
||||
"crypto/fipsmodule/sha/sha1.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha256.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha512.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/fors.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/thash.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/wots.cc.inc",
|
||||
"crypto/fipsmodule/tls/kdf.cc.inc",
|
||||
]
|
||||
|
||||
@@ -406,11 +411,7 @@ crypto_sources = [
|
||||
"crypto/sha/sha256.cc",
|
||||
"crypto/sha/sha512.cc",
|
||||
"crypto/siphash/siphash.cc",
|
||||
"crypto/slhdsa/fors.cc",
|
||||
"crypto/slhdsa/merkle.cc",
|
||||
"crypto/slhdsa/slhdsa.cc",
|
||||
"crypto/slhdsa/thash.cc",
|
||||
"crypto/slhdsa/wots.cc",
|
||||
"crypto/stack/stack.cc",
|
||||
"crypto/thread.cc",
|
||||
"crypto/thread_none.cc",
|
||||
@@ -619,6 +620,12 @@ crypto_internal_headers = [
|
||||
"crypto/fipsmodule/rsa/internal.h",
|
||||
"crypto/fipsmodule/service_indicator/internal.h",
|
||||
"crypto/fipsmodule/sha/internal.h",
|
||||
"crypto/fipsmodule/slhdsa/address.h",
|
||||
"crypto/fipsmodule/slhdsa/fors.h",
|
||||
"crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"crypto/fipsmodule/slhdsa/params.h",
|
||||
"crypto/fipsmodule/slhdsa/thash.h",
|
||||
"crypto/fipsmodule/slhdsa/wots.h",
|
||||
"crypto/fipsmodule/tls/internal.h",
|
||||
"crypto/hrss/internal.h",
|
||||
"crypto/internal.h",
|
||||
@@ -633,13 +640,6 @@ crypto_internal_headers = [
|
||||
"crypto/rand_extra/getrandom_fillin.h",
|
||||
"crypto/rand_extra/sysrand_internal.h",
|
||||
"crypto/rsa_extra/internal.h",
|
||||
"crypto/slhdsa/address.h",
|
||||
"crypto/slhdsa/fors.h",
|
||||
"crypto/slhdsa/internal.h",
|
||||
"crypto/slhdsa/merkle.h",
|
||||
"crypto/slhdsa/params.h",
|
||||
"crypto/slhdsa/thash.h",
|
||||
"crypto/slhdsa/wots.h",
|
||||
"crypto/trust_token/internal.h",
|
||||
"crypto/x509/ext_dat.h",
|
||||
"crypto/x509/internal.h",
|
||||
|
||||
+11
-11
@@ -78,6 +78,11 @@
|
||||
"crypto/fipsmodule/sha/sha1.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha256.cc.inc",
|
||||
"crypto/fipsmodule/sha/sha512.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/fors.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/merkle.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/slhdsa.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/thash.cc.inc",
|
||||
"crypto/fipsmodule/slhdsa/wots.cc.inc",
|
||||
"crypto/fipsmodule/tls/kdf.cc.inc"
|
||||
],
|
||||
"asm": [
|
||||
@@ -390,11 +395,7 @@
|
||||
"crypto/sha/sha256.cc",
|
||||
"crypto/sha/sha512.cc",
|
||||
"crypto/siphash/siphash.cc",
|
||||
"crypto/slhdsa/fors.cc",
|
||||
"crypto/slhdsa/merkle.cc",
|
||||
"crypto/slhdsa/slhdsa.cc",
|
||||
"crypto/slhdsa/thash.cc",
|
||||
"crypto/slhdsa/wots.cc",
|
||||
"crypto/stack/stack.cc",
|
||||
"crypto/thread.cc",
|
||||
"crypto/thread_none.cc",
|
||||
@@ -601,6 +602,12 @@
|
||||
"crypto/fipsmodule/rsa/internal.h",
|
||||
"crypto/fipsmodule/service_indicator/internal.h",
|
||||
"crypto/fipsmodule/sha/internal.h",
|
||||
"crypto/fipsmodule/slhdsa/address.h",
|
||||
"crypto/fipsmodule/slhdsa/fors.h",
|
||||
"crypto/fipsmodule/slhdsa/merkle.h",
|
||||
"crypto/fipsmodule/slhdsa/params.h",
|
||||
"crypto/fipsmodule/slhdsa/thash.h",
|
||||
"crypto/fipsmodule/slhdsa/wots.h",
|
||||
"crypto/fipsmodule/tls/internal.h",
|
||||
"crypto/hrss/internal.h",
|
||||
"crypto/internal.h",
|
||||
@@ -615,13 +622,6 @@
|
||||
"crypto/rand_extra/getrandom_fillin.h",
|
||||
"crypto/rand_extra/sysrand_internal.h",
|
||||
"crypto/rsa_extra/internal.h",
|
||||
"crypto/slhdsa/address.h",
|
||||
"crypto/slhdsa/fors.h",
|
||||
"crypto/slhdsa/internal.h",
|
||||
"crypto/slhdsa/merkle.h",
|
||||
"crypto/slhdsa/params.h",
|
||||
"crypto/slhdsa/thash.h",
|
||||
"crypto/slhdsa/wots.h",
|
||||
"crypto/trust_token/internal.h",
|
||||
"crypto/x509/ext_dat.h",
|
||||
"crypto/x509/internal.h",
|
||||
|
||||
Reference in New Issue
Block a user