aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/xmss/xmss_wots_parameters.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/xmss/xmss_wots_parameters.cpp')
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_parameters.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/lib/pubkey/xmss/xmss_wots_parameters.cpp b/src/lib/pubkey/xmss/xmss_wots_parameters.cpp
new file mode 100644
index 000000000..b908afeb4
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_parameters.cpp
@@ -0,0 +1,130 @@
+/**
+ * XMSS WOTS Parameters
+ * Descibes a signature method for XMSS Winternitz One Time Signatures,
+ * as defined in:
+ * [1] XMSS: Extended Hash-Based Signatures,
+ * draft-itrf-cfrg-xmss-hash-based-signatures-06
+ * Release: July 2016.
+ * https://datatracker.ietf.org/doc/
+ * draft-irtf-cfrg-xmss-hash-based-signatures/?include_text=1
+ *
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#include <botan/xmss_wots_parameters.h>
+
+namespace Botan {
+
+const std::map<std::string, XMSS_WOTS_Parameters::ots_algorithm_t>
+ XMSS_WOTS_Parameters::m_oid_name_lut =
+ {
+ { "WOTSP_SHA2-256_W16", WOTSP_SHA2_256_W16 },
+ { "WOTSP_SHA2-512_W16", WOTSP_SHA2_512_W16 }
+ };
+
+XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(const std::string& algo_name)
+ : XMSS_WOTS_Parameters(m_oid_name_lut.at(algo_name))
+ {}
+
+XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(ots_algorithm_t oid)
+ : m_oid(oid)
+ {
+ switch(oid)
+ {
+ case WOTSP_SHA2_256_W16:
+ m_element_size = 32;
+ m_w = 16;
+ m_len = 67;
+ m_name = "WOTSP_SHA2-256_W16";
+ m_hash_name = "SHA-256";
+ m_strength = 256;
+ break;
+ case WOTSP_SHA2_512_W16:
+ m_element_size = 64;
+ m_w = 16;
+ m_len = 131;
+ m_name = "WOTSP_SHA2-512_W16";
+ m_hash_name = "SHA-512";
+ m_strength = 512;
+ break;
+// FIXME: Uncomment once SHAKE128/256 implementation is available in Botan.
+// case WOTSP_SHAKE128_W16:
+// m_element_size = 32;
+// m_w = 16;
+// m_len = 67;
+// m_name = "WOTSP_SHAKE128_W16";
+// m_hash_name = "<MISSING>";
+// m_strength = 256;
+// break;
+// case WOTSP_SHAKE256_W16:
+// m_element_size = 64;
+// m_w = 16;
+// m_len = 131;
+// m_name = "WOTSP_SHAKE256_W16";
+// m_hash_name = "<MISSING>";
+// m_strength = 512;
+// break;
+ default:
+ throw Unsupported_Argument(
+ "Algorithm id does not match any XMSS WOTS algorithm id.");
+ break;
+ }
+
+ m_w == 16 ? m_lg_w = 4 : m_lg_w = 2;
+ m_len_1 = static_cast<size_t>(ceil((8 * element_size()) / m_lg_w));
+ m_len_2 = static_cast<size_t>(
+ floor(log2(m_len_1 * (wots_parameter() - 1)) / m_lg_w) + 1);
+ BOTAN_ASSERT(m_len == m_len_1 + m_len_2, "Invalid XMSS WOTS parameter "
+ "\"len\" detedted.");
+ }
+
+secure_vector<byte>
+XMSS_WOTS_Parameters::base_w(const secure_vector<byte>& msg, size_t out_size) const
+ {
+ secure_vector<byte> result;
+ size_t in = 0;
+ size_t total = 0;
+ size_t bits = 0;
+
+ for(size_t i = 0; i < out_size; i++)
+ {
+ if(bits == 0)
+ {
+ total = msg[in];
+ in++;
+ bits += 8;
+ }
+ bits -= m_lg_w;
+ result.push_back(static_cast<byte>((total >> bits) & (m_w - 1)));
+ }
+ return result;
+ }
+
+secure_vector<byte>
+XMSS_WOTS_Parameters::base_w(size_t value) const
+ {
+ value <<= (8 - ((m_len_2 * m_lg_w) % 8));
+ size_t len_2_bytes = static_cast<size_t>(
+ ceil(static_cast<float>(m_len_2 * m_lg_w) / 8.f));
+ secure_vector<byte> result;
+ XMSS_Tools::get().concat(result, value, len_2_bytes);
+ return base_w(result, m_len_2);
+ }
+
+void
+XMSS_WOTS_Parameters::append_checksum(secure_vector<byte>& data)
+ {
+ size_t csum = 0;
+
+ for(size_t i = 0; i < data.size(); i++)
+ {
+ csum += wots_parameter() - 1 - data[i];
+ }
+
+ secure_vector<byte> csum_bytes = base_w(csum);
+ std::move(csum_bytes.begin(), csum_bytes.end(), std::back_inserter(data));
+ }
+
+}