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