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