Botan 2.19.1
Crypto and TLS for C&
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
16namespace 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
27XMSS_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
83bool
84XMSS_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.
114void 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
void set_ots_address(uint32_t value)
Definition: xmss_address.h:164
uint32_t get_tree_index() const
Definition: xmss_address.h:297
void set_type(Type type)
Definition: xmss_address.h:111
void set_tree_height(uint32_t value)
Definition: xmss_address.h:251
void set_tree_index(uint32_t value)
Definition: xmss_address.h:313
void set_ltree_address(uint32_t value)
Definition: xmss_address.h:194
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)
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)
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
xmss_algorithm_t oid() const
size_t element_size() const
const XMSS_WOTS_Parameters & wots_parameters() const
Definition: xmss.h:141
const XMSS_Parameters & xmss_parameters() const
Definition: xmss.h:108
size_t unused_leaf_index() const
const XMSS_WOTS_PublicKey::TreeSignature & tree() const
static void concat(secure_vector< uint8_t > &target, const T &src)
Definition: xmss_tools.h:63
XMSS_Verification_Operation(const XMSS_PublicKey &public_key)
void update(const uint8_t msg[], size_t msg_len) override
bool is_valid_signature(const uint8_t sig[], size_t sig_len) override
ots_algorithm_t oid() const
Definition: xmss_wots.h:103
const wots_keysig_t & ots_signature() const
Definition: xmss_wots.h:153
const wots_keysig_t & authentication_path() const
Definition: xmss_wots.h:163
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65