diff options
Diffstat (limited to 'comm/third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.cpp')
-rw-r--r-- | comm/third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.cpp b/comm/third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.cpp new file mode 100644 index 0000000000..9a3fe085ab --- /dev/null +++ b/comm/third_party/botan/src/lib/pubkey/xmss/xmss_common_ops.cpp @@ -0,0 +1,74 @@ +/* + * XMSS Common Ops + * Operations shared by XMSS signature generation and verification operations. + * (C) 2016,2017 Matthias Gierlings + * + * Botan is released under the Simplified BSD License (see license.txt) + **/ + +#include <botan/internal/xmss_common_ops.h> + +namespace Botan { + +void +XMSS_Common_Ops::randomize_tree_hash(secure_vector<uint8_t>& result, + const secure_vector<uint8_t>& left, + const secure_vector<uint8_t>& right, + XMSS_Address& adrs, + const secure_vector<uint8_t>& seed, + XMSS_Hash& hash, + const XMSS_Parameters& params) + { + adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Key_Mode); + secure_vector<uint8_t> key { hash.prf(seed, adrs.bytes()) }; + + adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Mask_MSB_Mode); + secure_vector<uint8_t> bitmask_l { hash.prf(seed, adrs.bytes()) }; + + adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Mask_LSB_Mode); + secure_vector<uint8_t> bitmask_r { 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<uint8_t> concat_xor(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]; + } + + hash.h(result, key, concat_xor); + } + + +void +XMSS_Common_Ops::create_l_tree(secure_vector<uint8_t>& result, + wots_keysig_t pk, + XMSS_Address& adrs, + const secure_vector<uint8_t>& seed, + XMSS_Hash& hash, + const XMSS_Parameters& params) + { + size_t l = params.len(); + adrs.set_tree_height(0); + + while(l > 1) + { + for(size_t i = 0; i < l >> 1; i++) + { + adrs.set_tree_index(static_cast<uint32_t>(i)); + randomize_tree_hash(pk[i], pk[2 * i], pk[2 * i + 1], adrs, seed, hash, params); + } + 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]; + } + +} |