Botan 3.4.0
Crypto and TLS for C&
xmss_hash.h
Go to the documentation of this file.
1/*
2 * XMSS Hash
3 * (C) 2016,2017 Matthias Gierlings
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 **/
7
8#ifndef BOTAN_XMSS_HASH_H_
9#define BOTAN_XMSS_HASH_H_
10
11#include <botan/hash.h>
12
13#include <span>
14
15namespace Botan {
16
17class XMSS_Parameters;
18
19/**
20 * A collection of pseudorandom hash functions required for XMSS and WOTS
21 * computations.
22 **/
24 public:
25 XMSS_Hash(const XMSS_Parameters& params);
26
27 XMSS_Hash(const XMSS_Hash& hash);
28 XMSS_Hash(XMSS_Hash&& hash) = default;
29 ~XMSS_Hash() = default;
30
31 XMSS_Hash& operator=(const XMSS_Hash&) = delete;
33
34 std::string hash_function() const { return m_hash->name(); }
35
36 private:
37 inline void calculate_hash(const uint8_t hash_id,
39 std::span<const uint8_t> key,
40 std::span<const uint8_t> data) {
41 m_hash->update(m_zero_padding);
42 m_hash->update(hash_id);
43 m_hash->update(key.data(), key.size());
44 m_hash->update(data.data(), data.size());
45 m_hash->final(result);
46 }
47
48 public:
49 /**
50 * Pseudorandom function creating a hash out of a key and data using
51 * a cryptographic hash function.
52 *
53 * @param[out] result The hash calculated using key and data.
54 * @param[in] key An n-byte key value.
55 * @param[in] data A 32-byte XMSS_Address data value
56 **/
57 inline void prf(secure_vector<uint8_t>& result, std::span<const uint8_t> key, std::span<const uint8_t> data) {
58 calculate_hash(0x03, result, key, data);
59 }
60
61 /**
62 * Pseudoranom function creating a hash out of a key and data using
63 * a cryptographic hash function for key derivation.
64 *
65 * This function is described in NIST SP.800-208 Section 5 as a
66 * separate PRF to avoid a multi-target attack vector.
67 *
68 * @param[out] result The hash calculated using key and data.
69 * @param[in] key An n-byte key value.
70 * @param[in] data A 32-byte XMSS_Address data value
71 **/
73 std::span<const uint8_t> key,
74 std::span<const uint8_t> data) {
75 calculate_hash(0x04, result, key, data);
76 }
77
78 /**
79 * F is a keyed cryptographic hash function used by the WOTS+ algorithm.
80 *
81 * @param[out] result The hash calculated using key and data.
82 * @param[in] key key of length n bytes.
83 * @param[in] data string of arbitrary length.
84 **/
85 void f(secure_vector<uint8_t>& result, std::span<const uint8_t> key, std::span<const uint8_t> data) {
86 calculate_hash(0x00, result, key, data);
87 }
88
89 /**
90 * Cryptographic hash function h accepting n byte keys and 2n byte
91 * strings of data.
92 *
93 * @param[out] result The hash calculated using key and data.
94 * @param[in] key key of length n bytes.
95 * @param[in] data string of 2n bytes length.
96 **/
97 void h(secure_vector<uint8_t>& result, std::span<const uint8_t> key, std::span<const uint8_t> data) {
98 calculate_hash(0x01, result, key, data);
99 }
100
101 /**
102 * Cryptographic hash function h accepting 3n byte keys and data
103 * strings of arbitrary length.
104 *
105 * @param randomness n-byte value.
106 * @param root n-byte root node.
107 * @param index_bytes Index value padded with leading zeros.
108 * @param data string of arbitrary length.
109 *
110 * @return hash value of n-bytes length.
111 **/
112 secure_vector<uint8_t> h_msg(std::span<const uint8_t> randomness,
113 std::span<const uint8_t> root,
114 std::span<const uint8_t> index_bytes,
115 std::span<const uint8_t> data) {
116 h_msg_init(randomness, root, index_bytes);
117 h_msg_update(data);
118 return m_msg_hash->final();
119 }
120
121 /**
122 * Initializes buffered h_msg computation with prefix data.
123 *
124 * @param randomness random n-byte value.
125 * @param root n-byte root node.
126 * @param index_bytes Index value padded with leading zeros.
127 **/
128 void h_msg_init(std::span<const uint8_t> randomness,
129 std::span<const uint8_t> root,
130 std::span<const uint8_t> index_bytes);
131
132 /**
133 * Adds a message block to buffered h_msg computation.
134 *
135 * @param data A message block
136 **/
137 void h_msg_update(std::span<const uint8_t> data);
138
139 /**
140 * Finalizes buffered h_msg computation and retrieves the result.
141 *
142 * @return Hash calculated using the prefix set by h_msg_init() and
143 * message blocks provided through calls to h_msg_update().
144 **/
146
147 size_t output_length() const { return m_hash->output_length(); }
148
149 private:
150 std::unique_ptr<HashFunction> m_hash;
151 std::unique_ptr<HashFunction> m_msg_hash;
152
153 /// Hash id prefixes (for domain separation) prepended to the hash input
154 /// are big-endian representations with `hash_id_length` bytes. See the
155 /// definition of the `toByte` function in RFC 8391 and truncated hash
156 /// parameter sets in NIST SP-800-208.
157 std::vector<uint8_t> m_zero_padding;
158};
159
160} // namespace Botan
161
162#endif
~XMSS_Hash()=default
std::string hash_function() const
Definition xmss_hash.h:34
size_t output_length() const
Definition xmss_hash.h:147
XMSS_Hash & operator=(XMSS_Hash &&)=default
XMSS_Hash(XMSS_Hash &&hash)=default
secure_vector< uint8_t > h_msg_final()
Definition xmss_hash.cpp:49
void prf(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition xmss_hash.h:57
void h_msg_update(std::span< const uint8_t > data)
Definition xmss_hash.cpp:45
void prf_keygen(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition xmss_hash.h:72
secure_vector< uint8_t > h_msg(std::span< const uint8_t > randomness, std::span< const uint8_t > root, std::span< const uint8_t > index_bytes, std::span< const uint8_t > data)
Definition xmss_hash.h:112
XMSS_Hash(const XMSS_Parameters &params)
Definition xmss_hash.cpp:23
void f(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition xmss_hash.h:85
void h(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition xmss_hash.h:97
XMSS_Hash & operator=(const XMSS_Hash &)=delete
void h_msg_init(std::span< const uint8_t > randomness, std::span< const uint8_t > root, std::span< const uint8_t > index_bytes)
Definition xmss_hash.cpp:34
int(* final)(unsigned char *, CTX *)
Gf448Elem root(const Gf448Elem &elem)
Compute the root of elem in the field.
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61