Botan 3.0.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 {
25 public:
26 XMSS_Hash(const XMSS_Parameters& params);
27
28 XMSS_Hash(const XMSS_Hash& hash);
29 XMSS_Hash(XMSS_Hash&& hash) = default;
30 ~XMSS_Hash() = default;
31
32 XMSS_Hash& operator=(const XMSS_Hash&) = delete;
34
35 std::string hash_function() const { return m_hash->name(); }
36
37 private:
38 inline void calculate_hash(const uint8_t hash_id,
40 std::span<const uint8_t> key,
41 std::span<const uint8_t> data)
42 {
43 m_hash->update(m_zero_padding);
44 m_hash->update(hash_id);
45 m_hash->update(key.data(), key.size());
46 m_hash->update(data.data(), data.size());
47 m_hash->final(result);
48 }
49
50 public:
51 /**
52 * Pseudorandom function creating a hash out of a key and data using
53 * a cryptographic hash function.
54 *
55 * @param[out] result The hash calculated using key and data.
56 * @param[in] key An n-byte key value.
57 * @param[in] data A 32-byte XMSS_Address data value
58 **/
59 inline void prf(secure_vector<uint8_t>& result,
60 std::span<const uint8_t> key,
61 std::span<const uint8_t> data)
62 {
63 calculate_hash(0x03, result, key, data);
64 }
65
66 /**
67 * Pseudoranom function creating a hash out of a key and data using
68 * a cryptographic hash function for key derivation.
69 *
70 * This function is described in NIST SP.800-208 Section 5 as a
71 * separate PRF to avoid a multi-target attack vector.
72 *
73 * @param[out] result The hash calculated using key and data.
74 * @param[in] key An n-byte key value.
75 * @param[in] data A 32-byte XMSS_Address data value
76 **/
78 std::span<const uint8_t> key,
79 std::span<const uint8_t> data)
80 {
81 calculate_hash(0x04, result, key, data);
82 }
83
84 /**
85 * F is a keyed cryptographic hash function used by the WOTS+ algorithm.
86 *
87 * @param[out] result The hash calculated using key and data.
88 * @param[in] key key of length n bytes.
89 * @param[in] data string of arbitrary length.
90 **/
92 std::span<const uint8_t> key,
93 std::span<const uint8_t> data)
94 {
95 calculate_hash(0x00, result, key, data);
96 }
97
98 /**
99 * Cryptographic hash function h accepting n byte keys and 2n byte
100 * strings of data.
101 *
102 * @param[out] result The hash calculated using key and data.
103 * @param[in] key key of length n bytes.
104 * @param[in] data string of 2n bytes length.
105 **/
107 std::span<const uint8_t> key,
108 std::span<const uint8_t> data)
109 {
110 calculate_hash(0x01, result, key, data);
111 }
112
113 /**
114 * Cryptographic hash function h accepting 3n byte keys and data
115 * strings of arbitrary length.
116 *
117 * @param randomness n-byte value.
118 * @param root n-byte root node.
119 * @param index_bytes Index value padded with leading zeros.
120 * @param data string of arbitrary length.
121 *
122 * @return hash value of n-bytes length.
123 **/
124 secure_vector<uint8_t> h_msg(std::span<const uint8_t> randomness,
125 std::span<const uint8_t> root,
126 std::span<const uint8_t> index_bytes,
127 std::span<const uint8_t> data)
128 {
129 h_msg_init(randomness, root, index_bytes);
130 h_msg_update(data);
131 return m_msg_hash->final();
132 }
133
134 /**
135 * Initializes buffered h_msg computation with prefix data.
136 *
137 * @param randomness random n-byte value.
138 * @param root n-byte root node.
139 * @param index_bytes Index value padded with leading zeros.
140 **/
141 void h_msg_init(std::span<const uint8_t> randomness,
142 std::span<const uint8_t> root,
143 std::span<const uint8_t> index_bytes);
144
145 /**
146 * Adds a message block to buffered h_msg computation.
147 *
148 * @param data A message block
149 **/
150 void h_msg_update(std::span<const uint8_t> data);
151
152 /**
153 * Finalizes buffered h_msg computation and retrieves the result.
154 *
155 * @return Hash calculated using the prefix set by h_msg_init() and
156 * message blocks provided through calls to h_msg_update().
157 **/
159
160 size_t output_length() const { return m_hash->output_length(); }
161
162 private:
163 std::unique_ptr<HashFunction> m_hash;
164 std::unique_ptr<HashFunction> m_msg_hash;
165
166 /// Hash id prefixes (for domain separation) prepended to the hash input
167 /// are big-endian representations with `hash_id_length` bytes. See the
168 /// definition of the `toByte` function in RFC 8391 and truncated hash
169 /// parameter sets in NIST SP-800-208.
170 std::vector<uint8_t> m_zero_padding;
171
172 };
173
174}
175
176#endif
~XMSS_Hash()=default
std::string hash_function() const
Definition: xmss_hash.h:35
size_t output_length() const
Definition: xmss_hash.h:160
XMSS_Hash & operator=(XMSS_Hash &&)=default
XMSS_Hash(XMSS_Hash &&hash)=default
secure_vector< uint8_t > h_msg_final()
Definition: xmss_hash.cpp:53
void prf(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition: xmss_hash.h:59
void h_msg_update(std::span< const uint8_t > data)
Definition: xmss_hash.cpp:48
void prf_keygen(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition: xmss_hash.h:77
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:124
void f(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition: xmss_hash.h:91
void h(secure_vector< uint8_t > &result, std::span< const uint8_t > key, std::span< const uint8_t > data)
Definition: xmss_hash.h:106
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:36
int(* final)(unsigned char *, CTX *)
Definition: alg_id.cpp:12
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64