Botan 3.6.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
13#include <botan/internal/xmss_common_ops.h>
14#include <botan/internal/xmss_tools.h>
15#include <array>
16
17namespace Botan {
18
20 m_pub_key(public_key), m_hash(public_key.xmss_parameters()), m_msg_buf(0) {}
21
22secure_vector<uint8_t> XMSS_Verification_Operation::root_from_signature(const XMSS_Signature& sig,
23 const secure_vector<uint8_t>& msg,
24 XMSS_Address& adrs,
25 const secure_vector<uint8_t>& seed) {
26 const auto& params = m_pub_key.xmss_parameters();
27
28 const uint32_t next_index = static_cast<uint32_t>(sig.unused_leaf_index());
30 adrs.set_ots_address(next_index);
31
32 XMSS_WOTS_PublicKey pub_key_ots(params.ots_oid(), seed, sig.tree().ots_signature, msg, adrs, m_hash);
33
35 adrs.set_ltree_address(next_index);
36
37 std::array<secure_vector<uint8_t>, 2> node;
38 XMSS_Common_Ops::create_l_tree(node[0], pub_key_ots.key_data(), adrs, seed, m_hash, params);
39
41 adrs.set_tree_index(next_index);
42
43 for(size_t k = 0; k < params.tree_height(); k++) {
44 adrs.set_tree_height(static_cast<uint32_t>(k));
45 if(((next_index / (static_cast<size_t>(1) << k)) & 0x01) == 0) {
46 adrs.set_tree_index(adrs.get_tree_index() >> 1);
48 node[1], node[0], sig.tree().authentication_path[k], adrs, seed, m_hash, params);
49 } else {
50 adrs.set_tree_index((adrs.get_tree_index() - 1) >> 1);
52 node[1], sig.tree().authentication_path[k], node[0], adrs, seed, m_hash, params);
53 }
54 node[0] = node[1];
55 }
56 return node[0];
57}
58
59bool XMSS_Verification_Operation::verify(const XMSS_Signature& sig,
60 const secure_vector<uint8_t>& msg,
61 const XMSS_PublicKey& public_key) {
62 XMSS_Address adrs;
63 secure_vector<uint8_t> index_bytes;
64 XMSS_Tools::concat(index_bytes, sig.unused_leaf_index(), m_pub_key.xmss_parameters().element_size());
65 secure_vector<uint8_t> msg_digest = m_hash.h_msg(sig.randomness(), public_key.root(), index_bytes, msg);
66
67 secure_vector<uint8_t> node = root_from_signature(sig, msg_digest, adrs, public_key.public_seed());
68
69 return (node == public_key.root());
70}
71
72// FIXME: XMSS signature verification requires the "randomness" parameter out
73// of the XMSS signature, which is part of the prefix that is hashed before
74// msg. Since the signature is unknown till sign() is called all message
75// content has to be buffered. For large messages this can be inconvenient or
76// impossible.
77// Possible solution: Change PK_Ops::Verification interface to take the
78// signature as constructor argument, make sign a parameterless member call.
79void XMSS_Verification_Operation::update(std::span<const uint8_t> input) {
80 m_msg_buf.insert(m_msg_buf.end(), input.begin(), input.end());
81}
82
83bool XMSS_Verification_Operation::is_valid_signature(std::span<const uint8_t> sig) {
84 try {
85 XMSS_Signature signature(m_pub_key.xmss_parameters().oid(), sig);
86 bool result = verify(signature, m_msg_buf, m_pub_key);
87 m_msg_buf.clear();
88 return result;
89 } catch(...) {
90 m_msg_buf.clear();
91 return false;
92 }
93}
94
95} // namespace Botan
void set_ots_address(uint32_t value)
uint32_t get_tree_index() const
void set_type(Type type)
void set_tree_height(uint32_t value)
void set_tree_index(uint32_t value)
void set_ltree_address(uint32_t value)
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(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_algorithm_t oid() const
size_t element_size() const
const XMSS_Parameters & xmss_parameters() const
Definition xmss.h:120
const XMSS_Signature::TreeSignature & tree() const
size_t unused_leaf_index() const
static void concat(secure_vector< uint8_t > &target, const T &src)
Definition xmss_tools.h:54
bool is_valid_signature(std::span< const uint8_t > sign) override
XMSS_Verification_Operation(const XMSS_PublicKey &public_key)
void update(std::span< const uint8_t > input) override
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61