/src/botan/src/lib/pubkey/xmss/xmss_wots_parameters.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * XMSS WOTS Parameters |
3 | | * Descibes a signature method for XMSS Winternitz One Time Signatures, |
4 | | * as defined in: |
5 | | * [1] XMSS: Extended Hash-Based Signatures, |
6 | | * Request for Comments: 8391 |
7 | | * Release: May 2018. |
8 | | * https://datatracker.ietf.org/doc/rfc8391/ |
9 | | * |
10 | | * (C) 2016,2017,2018 Matthias Gierlings |
11 | | * |
12 | | * Botan is released under the Simplified BSD License (see license.txt) |
13 | | **/ |
14 | | |
15 | | #include <botan/xmss_wots.h> |
16 | | #include <botan/internal/xmss_tools.h> |
17 | | #include <botan/exceptn.h> |
18 | | #include <cmath> |
19 | | |
20 | | namespace Botan { |
21 | | |
22 | | XMSS_WOTS_Parameters::ots_algorithm_t |
23 | | XMSS_WOTS_Parameters::xmss_wots_id_from_string(const std::string& param_set) |
24 | 0 | { |
25 | 0 | if(param_set == "WOTSP-SHA2_256") |
26 | 0 | { return WOTSP_SHA2_256; } |
27 | 0 | if(param_set == "WOTSP-SHA2_512") |
28 | 0 | { return WOTSP_SHA2_512; } |
29 | 0 | if(param_set == "WOTSP-SHAKE_256") |
30 | 0 | { return WOTSP_SHAKE_256; } |
31 | 0 | if(param_set == "WOTSP-SHAKE_512") |
32 | 0 | { return WOTSP_SHAKE_512; } |
33 | 0 | throw Invalid_Argument("Unknown XMSS-WOTS algorithm param '" + param_set + "'"); |
34 | 0 | } |
35 | | |
36 | | XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(const std::string& param_set) |
37 | | : XMSS_WOTS_Parameters(xmss_wots_id_from_string(param_set)) |
38 | 0 | {} |
39 | | |
40 | | XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(ots_algorithm_t oid) |
41 | | : m_oid(oid) |
42 | 0 | { |
43 | 0 | switch(oid) |
44 | 0 | { |
45 | 0 | case WOTSP_SHA2_256: |
46 | 0 | m_element_size = 32; |
47 | 0 | m_w = 16; |
48 | 0 | m_len = 67; |
49 | 0 | m_name = "WOTSP-SHA2_256"; |
50 | 0 | m_hash_name = "SHA-256"; |
51 | 0 | m_strength = 256; |
52 | 0 | break; |
53 | 0 | case WOTSP_SHA2_512: |
54 | 0 | m_element_size = 64; |
55 | 0 | m_w = 16; |
56 | 0 | m_len = 131; |
57 | 0 | m_name = "WOTSP-SHA2_512"; |
58 | 0 | m_hash_name = "SHA-512"; |
59 | 0 | m_strength = 512; |
60 | 0 | break; |
61 | 0 | case WOTSP_SHAKE_256: |
62 | 0 | m_element_size = 32; |
63 | 0 | m_w = 16; |
64 | 0 | m_len = 67; |
65 | 0 | m_name = "WOTSP-SHAKE_256"; |
66 | 0 | m_hash_name = "SHAKE-128(256)"; |
67 | 0 | m_strength = 256; |
68 | 0 | break; |
69 | 0 | case WOTSP_SHAKE_512: |
70 | 0 | m_element_size = 64; |
71 | 0 | m_w = 16; |
72 | 0 | m_len = 131; |
73 | 0 | m_name = "WOTSP-SHAKE_512"; |
74 | 0 | m_hash_name = "SHAKE-256(512)"; |
75 | 0 | m_strength = 512; |
76 | 0 | break; |
77 | 0 | default: |
78 | 0 | throw Not_Implemented("Algorithm id does not match any known XMSS WOTS algorithm id."); |
79 | 0 | break; |
80 | 0 | } |
81 | | |
82 | 0 | m_lg_w = (m_w == 16) ? 4 : 2; |
83 | 0 | m_len_1 = static_cast<size_t>(std::ceil((8 * element_size()) / m_lg_w)); |
84 | 0 | m_len_2 = static_cast<size_t>( |
85 | 0 | floor(log2(m_len_1 * (wots_parameter() - 1)) / m_lg_w) + 1); |
86 | 0 | BOTAN_ASSERT(m_len == m_len_1 + m_len_2, "Invalid XMSS WOTS parameter " |
87 | 0 | "\"len\" detedted."); |
88 | 0 | } |
89 | | |
90 | | secure_vector<uint8_t> |
91 | | XMSS_WOTS_Parameters::base_w(const secure_vector<uint8_t>& msg, size_t out_size) const |
92 | 0 | { |
93 | 0 | secure_vector<uint8_t> result; |
94 | 0 | size_t in = 0; |
95 | 0 | size_t total = 0; |
96 | 0 | size_t bits = 0; |
97 | |
|
98 | 0 | for(size_t i = 0; i < out_size; i++) |
99 | 0 | { |
100 | 0 | if(bits == 0) |
101 | 0 | { |
102 | 0 | total = msg[in]; |
103 | 0 | in++; |
104 | 0 | bits += 8; |
105 | 0 | } |
106 | 0 | bits -= m_lg_w; |
107 | 0 | result.push_back(static_cast<uint8_t>((total >> bits) & (m_w - 1))); |
108 | 0 | } |
109 | 0 | return result; |
110 | 0 | } |
111 | | |
112 | | secure_vector<uint8_t> |
113 | | XMSS_WOTS_Parameters::base_w(size_t value) const |
114 | 0 | { |
115 | 0 | value <<= (8 - ((m_len_2 * m_lg_w) % 8)); |
116 | 0 | size_t len_2_bytes = static_cast<size_t>( |
117 | 0 | std::ceil(static_cast<float>(m_len_2 * m_lg_w) / 8.f)); |
118 | 0 | secure_vector<uint8_t> result; |
119 | 0 | XMSS_Tools::concat(result, value, len_2_bytes); |
120 | 0 | return base_w(result, m_len_2); |
121 | 0 | } |
122 | | |
123 | | void |
124 | | XMSS_WOTS_Parameters::append_checksum(secure_vector<uint8_t>& data) |
125 | 0 | { |
126 | 0 | size_t csum = 0; |
127 | |
|
128 | 0 | for(size_t i = 0; i < data.size(); i++) |
129 | 0 | { |
130 | 0 | csum += wots_parameter() - 1 - data[i]; |
131 | 0 | } |
132 | |
|
133 | 0 | secure_vector<uint8_t> csum_bytes = base_w(csum); |
134 | 0 | std::move(csum_bytes.begin(), csum_bytes.end(), std::back_inserter(data)); |
135 | 0 | } |
136 | | |
137 | | } |