aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/xmss/xmss_common_ops.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/xmss/xmss_common_ops.cpp')
-rw-r--r--src/lib/pubkey/xmss/xmss_common_ops.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/lib/pubkey/xmss/xmss_common_ops.cpp b/src/lib/pubkey/xmss/xmss_common_ops.cpp
new file mode 100644
index 000000000..dd139a349
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_common_ops.cpp
@@ -0,0 +1,70 @@
+/**
+ * XMSS Common Ops
+ * Operations shared by XMSS signature generation and verification operations.
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#include <botan/xmss_common_ops.h>
+
+namespace Botan {
+
+void
+XMSS_Common_Ops::randomize_tree_hash(secure_vector<byte>& result,
+ const secure_vector<byte>& left,
+ const secure_vector<byte>& right,
+ XMSS_Address& adrs,
+ const secure_vector<byte>& seed)
+ {
+ adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Key_Mode);
+ secure_vector<byte> key { m_hash.prf(seed, adrs.bytes()) };
+
+ adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Mask_MSB_Mode);
+ secure_vector<byte> bitmask_l { m_hash.prf(seed, adrs.bytes()) };
+
+ adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Mask_LSB_Mode);
+ secure_vector<byte> bitmask_r { m_hash.prf(seed, adrs.bytes()) };
+
+ BOTAN_ASSERT(bitmask_l.size() == left.size() &&
+ bitmask_r.size() == right.size(),
+ "Bitmask size doesn't match node size.");
+
+ secure_vector<byte> concat_xor(m_xmss_params.element_size() * 2);
+ for(size_t i = 0; i < left.size(); i++)
+ {
+ concat_xor[i] = left[i] ^ bitmask_l[i];
+ concat_xor[i + left.size()] = right[i] ^ bitmask_r[i];
+ }
+
+ m_hash.h(result, key, concat_xor);
+ }
+
+
+void
+XMSS_Common_Ops::create_l_tree(secure_vector<byte>& result,
+ wots_keysig_t pk,
+ XMSS_Address& adrs,
+ const secure_vector<byte>& seed)
+ {
+ size_t l = m_xmss_params.len();
+ adrs.set_tree_height(0);
+
+ while(l > 1)
+ {
+ for(size_t i = 0; i < l >> 1; i++)
+ {
+ adrs.set_tree_index(i);
+ randomize_tree_hash(pk[i], pk[2 * i], pk[2 * i + 1], adrs, seed);
+ }
+ if(l & 0x01)
+ {
+ pk[l >> 1] = pk[l - 1];
+ }
+ l = (l >> 1) + (l & 0x01);
+ adrs.set_tree_height(adrs.get_tree_height() + 1);
+ }
+ result = pk[0];
+ }
+
+}