1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
/*
* XMSS Signature
* (C) 2016,2017,2018 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
**/
#include <botan/internal/xmss_signature.h>
#include <cmath>
namespace Botan {
XMSS_Signature::XMSS_Signature(XMSS_Parameters::xmss_algorithm_t oid,
const secure_vector<uint8_t>& raw_sig)
: m_leaf_idx(0), m_randomness(0, 0x00), m_tree_sig()
{
XMSS_Parameters xmss_params(oid);
if(raw_sig.size() != (xmss_params.len() + xmss_params.tree_height() + 1)
* xmss_params.element_size() + sizeof(m_leaf_idx))
{
throw Decoding_Error("XMSS signature size invalid.");
}
for(size_t i = 0; i < 8; i++)
{ m_leaf_idx = ((m_leaf_idx << 8) | raw_sig[i]); }
if(m_leaf_idx >= (1ull << xmss_params.tree_height()))
{
throw Decoding_Error("XMSS signature leaf index out of bounds.");
}
auto begin = raw_sig.begin() + sizeof(m_leaf_idx);
auto end = begin + xmss_params.element_size();
std::copy(begin, end, std::back_inserter(m_randomness));
for(size_t i = 0; i < xmss_params.len(); i++)
{
begin = end;
end = begin + xmss_params.element_size();
m_tree_sig.ots_signature().push_back(secure_vector<uint8_t>(0));
m_tree_sig.ots_signature().back().reserve(
xmss_params.element_size());
std::copy(begin,
end,
std::back_inserter(m_tree_sig.ots_signature().back()));
}
for(size_t i = 0; i < xmss_params.tree_height(); i++)
{
begin = end;
end = begin + xmss_params.element_size();
m_tree_sig.authentication_path().push_back(secure_vector<uint8_t>(0));
m_tree_sig.authentication_path().back().reserve(
xmss_params.element_size());
std::copy(begin,
end,
std::back_inserter(m_tree_sig.authentication_path().back()));
}
}
secure_vector<uint8_t> XMSS_Signature::bytes() const
{
secure_vector<uint8_t> result
{
static_cast<uint8_t>(m_leaf_idx >> 56U),
static_cast<uint8_t>(m_leaf_idx >> 48U),
static_cast<uint8_t>(m_leaf_idx >> 40U),
static_cast<uint8_t>(m_leaf_idx >> 32U),
static_cast<uint8_t>(m_leaf_idx >> 24U),
static_cast<uint8_t>(m_leaf_idx >> 16U),
static_cast<uint8_t>(m_leaf_idx >> 8U),
static_cast<uint8_t>(m_leaf_idx)
};
std::copy(m_randomness.begin(),
m_randomness.end(),
std::back_inserter(result));
for(const auto& sig : tree().ots_signature())
{
std::copy(sig.begin(),
sig.end(),
std::back_inserter(result));
}
for(const auto& auth : tree().authentication_path())
{
std::copy(auth.begin(),
auth.end(),
std::back_inserter(result));
}
return result;
}
}
|