Botan  2.19.1
Crypto and TLS for C++11
xmss_verification_operation.cpp
Go to the documentation of this file.
1 /*
2  * XMSS Verification Operation
3  * Provides signature verification capabilities for Extended Hash-Based
4  * Signatures (XMSS).
5  *
6  * (C) 2016,2017 Matthias Gierlings
7  *
8  * Botan is released under the Simplified BSD License (see license.txt)
9  **/
10 
11 #include <botan/internal/xmss_verification_operation.h>
12 #include <botan/internal/xmss_common_ops.h>
13 #include <botan/internal/xmss_tools.h>
14 #include <array>
15 
16 namespace Botan {
17 
19  const XMSS_PublicKey& public_key) :
20  m_pub_key(public_key),
21  m_hash(public_key.xmss_hash_function()),
22  m_msg_buf(0)
23  {
24  }
25 
27 XMSS_Verification_Operation::root_from_signature(const XMSS_Signature& sig,
28  const secure_vector<uint8_t>& msg,
29  XMSS_Address& adrs,
30  const secure_vector<uint8_t>& seed)
31  {
32  const auto params = m_pub_key.xmss_parameters();
33 
34  const uint32_t next_index = static_cast<uint32_t>(sig.unused_leaf_index());
36  adrs.set_ots_address(next_index);
37 
38  XMSS_WOTS_PublicKey pub_key_ots(m_pub_key.wots_parameters().oid(),
39  msg,
40  sig.tree().ots_signature(),
41  adrs,
42  seed);
43 
45  adrs.set_ltree_address(next_index);
46 
47  std::array<secure_vector<uint8_t>, 2> node;
48  XMSS_Common_Ops::create_l_tree(node[0], pub_key_ots, adrs, seed, m_hash, params);
49 
51  adrs.set_tree_index(next_index);
52 
53  for(size_t k = 0; k < params.tree_height(); k++)
54  {
55  adrs.set_tree_height(static_cast<uint32_t>(k));
56  if(((next_index / (static_cast<size_t>(1) << k)) & 0x01) == 0)
57  {
58  adrs.set_tree_index(adrs.get_tree_index() >> 1);
60  node[0],
61  sig.tree().authentication_path()[k],
62  adrs,
63  seed,
64  m_hash,
65  params);
66  }
67  else
68  {
69  adrs.set_tree_index((adrs.get_tree_index() - 1) >> 1);
71  sig.tree().authentication_path()[k],
72  node[0],
73  adrs,
74  seed,
75  m_hash,
76  params);
77  }
78  node[0] = node[1];
79  }
80  return node[0];
81  }
82 
83 bool
84 XMSS_Verification_Operation::verify(const XMSS_Signature& sig,
85  const secure_vector<uint8_t>& msg,
86  const XMSS_PublicKey& public_key)
87  {
88  XMSS_Address adrs;
89  secure_vector<uint8_t> index_bytes;
90  XMSS_Tools::concat(index_bytes,
91  sig.unused_leaf_index(),
92  m_pub_key.xmss_parameters().element_size());
93  secure_vector<uint8_t> msg_digest =
94  m_hash.h_msg(sig.randomness(),
95  public_key.root(),
96  index_bytes,
97  msg);
98 
99  secure_vector<uint8_t> node = root_from_signature(sig,
100  msg_digest,
101  adrs,
102  public_key.public_seed());
103 
104  return (node == public_key.root());
105  }
106 
107 // FIXME: XMSS signature verification requires the "randomness" parameter out
108 // of the XMSS signature, which is part of the prefix that is hashed before
109 // msg. Since the signature is unknown till sign() is called all message
110 // content has to be buffered. For large messages this can be inconvenient or
111 // impossible.
112 // Possible solution: Change PK_Ops::Verification interface to take the
113 // signature as constructor argument, make sign a parameterless member call.
114 void XMSS_Verification_Operation::update(const uint8_t msg[], size_t msg_len)
115  {
116  std::copy(msg, msg + msg_len, std::back_inserter(m_msg_buf));
117  }
118 
120  size_t sig_len)
121  {
122  try
123  {
124  XMSS_Signature signature(m_pub_key.xmss_parameters().oid(),
125  secure_vector<uint8_t>(sig, sig + sig_len));
126  bool result = verify(signature, m_msg_buf, m_pub_key);
127  m_msg_buf.clear();
128  return result;
129  }
130  catch(...)
131  {
132  m_msg_buf.clear();
133  return false;
134  }
135  }
136 
137 }
138 
size_t element_size() const
size_t unused_leaf_index() const
void set_ots_address(uint32_t value)
Definition: xmss_address.h:164
void set_tree_height(uint32_t value)
Definition: xmss_address.h:251
static void create_l_tree(secure_vector< uint8_t > &result, wots_keysig_t pk, XMSS_Address &adrs, const secure_vector< uint8_t > &seed, XMSS_Hash &hash, const XMSS_Parameters &params)
void set_ltree_address(uint32_t value)
Definition: xmss_address.h:194
bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
secure_vector< uint8_t > h_msg(const secure_vector< uint8_t > &randomness, const secure_vector< uint8_t > &root, const secure_vector< uint8_t > &index_bytes, const secure_vector< uint8_t > &data)
Definition: xmss_hash.cpp:70
const XMSS_Parameters & xmss_parameters() const
Definition: xmss.h:108
xmss_algorithm_t oid() const
void update(const uint8_t msg[], size_t msg_len) override
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
const wots_keysig_t & ots_signature() const
Definition: xmss_wots.h:153
void set_type(Type type)
Definition: xmss_address.h:111
Definition: alg_id.cpp:13
XMSS_Verification_Operation(const XMSS_PublicKey &public_key)
static void concat(secure_vector< uint8_t > &target, const T &src)
Definition: xmss_tools.h:63
static void randomize_tree_hash(secure_vector< uint8_t > &result, const secure_vector< uint8_t > &left, const secure_vector< uint8_t > &right, XMSS_Address &adrs, const secure_vector< uint8_t > &seed, XMSS_Hash &hash, const XMSS_Parameters &params)
const XMSS_WOTS_Parameters & wots_parameters() const
Definition: xmss.h:141
const XMSS_WOTS_PublicKey::TreeSignature & tree() const
uint32_t get_tree_index() const
Definition: xmss_address.h:297
void set_tree_index(uint32_t value)
Definition: xmss_address.h:313
std::unique_ptr< HashFunction > m_hash
Definition: tpm.cpp:446
ots_algorithm_t oid() const
Definition: xmss_wots.h:103
const wots_keysig_t & authentication_path() const
Definition: xmss_wots.h:163