/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_parameters.h> |
16 | | #include <botan/exceptn.h> |
17 | | #include <cmath> |
18 | | |
19 | | namespace Botan { |
20 | | |
21 | | XMSS_WOTS_Parameters::ots_algorithm_t |
22 | | XMSS_WOTS_Parameters::xmss_wots_id_from_string(const std::string& param_set) |
23 | 0 | { |
24 | 0 | if(param_set == "WOTSP-SHA2_256") |
25 | 0 | { return WOTSP_SHA2_256; } |
26 | 0 | if(param_set == "WOTSP-SHA2_512") |
27 | 0 | { return WOTSP_SHA2_512; } |
28 | 0 | if(param_set == "WOTSP-SHAKE_256") |
29 | 0 | { return WOTSP_SHAKE_256; } |
30 | 0 | if(param_set == "WOTSP-SHAKE_512") |
31 | 0 | { return WOTSP_SHAKE_512; } |
32 | 0 | throw Invalid_Argument("Unknown XMSS-WOTS algorithm param '" + param_set + "'"); |
33 | 0 | } |
34 | | |
35 | | XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(const std::string& param_set) |
36 | | : XMSS_WOTS_Parameters(xmss_wots_id_from_string(param_set)) |
37 | 0 | {} |
38 | | |
39 | | XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(ots_algorithm_t oid) |
40 | | : m_oid(oid) |
41 | 0 | { |
42 | 0 | switch(oid) |
43 | 0 | { |
44 | 0 | case WOTSP_SHA2_256: |
45 | 0 | m_element_size = 32; |
46 | 0 | m_w = 16; |
47 | 0 | m_len = 67; |
48 | 0 | m_name = "WOTSP-SHA2_256"; |
49 | 0 | m_hash_name = "SHA-256"; |
50 | 0 | m_strength = 256; |
51 | 0 | break; |
52 | 0 | case WOTSP_SHA2_512: |
53 | 0 | m_element_size = 64; |
54 | 0 | m_w = 16; |
55 | 0 | m_len = 131; |
56 | 0 | m_name = "WOTSP-SHA2_512"; |
57 | 0 | m_hash_name = "SHA-512"; |
58 | 0 | m_strength = 512; |
59 | 0 | break; |
60 | 0 | case WOTSP_SHAKE_256: |
61 | 0 | m_element_size = 32; |
62 | 0 | m_w = 16; |
63 | 0 | m_len = 67; |
64 | 0 | m_name = "WOTSP-SHAKE_256"; |
65 | 0 | m_hash_name = "SHAKE-128(256)"; |
66 | 0 | m_strength = 256; |
67 | 0 | break; |
68 | 0 | case WOTSP_SHAKE_512: |
69 | 0 | m_element_size = 64; |
70 | 0 | m_w = 16; |
71 | 0 | m_len = 131; |
72 | 0 | m_name = "WOTSP-SHAKE_512"; |
73 | 0 | m_hash_name = "SHAKE-256(512)"; |
74 | 0 | m_strength = 512; |
75 | 0 | break; |
76 | 0 | default: |
77 | 0 | throw Not_Implemented("Algorithm id does not match any known XMSS WOTS algorithm id."); |
78 | 0 | break; |
79 | 0 | } |
80 | 0 | |
81 | 0 | m_lg_w = (m_w == 16) ? 4 : 2; |
82 | 0 | m_len_1 = static_cast<size_t>(std::ceil((8 * element_size()) / m_lg_w)); |
83 | 0 | m_len_2 = static_cast<size_t>( |
84 | 0 | floor(log2(m_len_1 * (wots_parameter() - 1)) / m_lg_w) + 1); |
85 | 0 | BOTAN_ASSERT(m_len == m_len_1 + m_len_2, "Invalid XMSS WOTS parameter " |
86 | 0 | "\"len\" detedted."); |
87 | 0 | } |
88 | | |
89 | | secure_vector<uint8_t> |
90 | | XMSS_WOTS_Parameters::base_w(const secure_vector<uint8_t>& msg, size_t out_size) const |
91 | 0 | { |
92 | 0 | secure_vector<uint8_t> result; |
93 | 0 | size_t in = 0; |
94 | 0 | size_t total = 0; |
95 | 0 | size_t bits = 0; |
96 | 0 |
|
97 | 0 | for(size_t i = 0; i < out_size; i++) |
98 | 0 | { |
99 | 0 | if(bits == 0) |
100 | 0 | { |
101 | 0 | total = msg[in]; |
102 | 0 | in++; |
103 | 0 | bits += 8; |
104 | 0 | } |
105 | 0 | bits -= m_lg_w; |
106 | 0 | result.push_back(static_cast<uint8_t>((total >> bits) & (m_w - 1))); |
107 | 0 | } |
108 | 0 | return result; |
109 | 0 | } |
110 | | |
111 | | secure_vector<uint8_t> |
112 | | XMSS_WOTS_Parameters::base_w(size_t value) const |
113 | 0 | { |
114 | 0 | value <<= (8 - ((m_len_2 * m_lg_w) % 8)); |
115 | 0 | size_t len_2_bytes = static_cast<size_t>( |
116 | 0 | std::ceil(static_cast<float>(m_len_2 * m_lg_w) / 8.f)); |
117 | 0 | secure_vector<uint8_t> result; |
118 | 0 | XMSS_Tools::concat(result, value, len_2_bytes); |
119 | 0 | return base_w(result, m_len_2); |
120 | 0 | } |
121 | | |
122 | | void |
123 | | XMSS_WOTS_Parameters::append_checksum(secure_vector<uint8_t>& data) |
124 | 0 | { |
125 | 0 | size_t csum = 0; |
126 | 0 |
|
127 | 0 | for(size_t i = 0; i < data.size(); i++) |
128 | 0 | { |
129 | 0 | csum += wots_parameter() - 1 - data[i]; |
130 | 0 | } |
131 | 0 |
|
132 | 0 | secure_vector<uint8_t> csum_bytes = base_w(csum); |
133 | 0 | std::move(csum_bytes.begin(), csum_bytes.end(), std::back_inserter(data)); |
134 | 0 | } |
135 | | |
136 | | } |