aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/xmss
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/xmss')
-rw-r--r--src/lib/pubkey/xmss/info.txt8
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_addressed_privatekey.h68
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h107
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_common_ops.cpp40
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_common_ops.h55
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_privatekey.cpp13
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_privatekey.h5
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_publickey.cpp13
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_publickey.h5
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_signature_operation.cpp52
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_signature_operation.h74
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_verification_operation.cpp68
-rw-r--r--src/lib/pubkey/xmss/xmss_wots_verification_operation.h66
13 files changed, 566 insertions, 8 deletions
diff --git a/src/lib/pubkey/xmss/info.txt b/src/lib/pubkey/xmss/info.txt
index bab541625..f23bb847b 100644
--- a/src/lib/pubkey/xmss/info.txt
+++ b/src/lib/pubkey/xmss/info.txt
@@ -10,9 +10,12 @@ xmss_publickey.cpp
xmss_signature.cpp
xmss_signature_operation.cpp
xmss_verification_operation.cpp
+xmss_wots_common_ops.cpp
xmss_wots_parameters.cpp
xmss_wots_privatekey.cpp
xmss_wots_publickey.cpp
+xmss_wots_signature_operation.cpp
+xmss_wots_verification_operation.cpp
</source>
<header:public>
@@ -33,6 +36,11 @@ xmss_wots_publickey.h
</header:public>
<header:internal>
+xmss_wots_addressed_privatekey.h
+xmss_wots_addressed_publickey.h
+xmss_wots_common_ops.h
+xmss_wots_signature_operation.h
+xmss_wots_verification_operation.h
xmss_signature.h
xmss_signature_operation.h
xmss_verification_operation.h
diff --git a/src/lib/pubkey/xmss/xmss_wots_addressed_privatekey.h b/src/lib/pubkey/xmss/xmss_wots_addressed_privatekey.h
new file mode 100644
index 000000000..e82cd1638
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_addressed_privatekey.h
@@ -0,0 +1,68 @@
+/**
+ * XMSS WOTS Addressed Private Key
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#ifndef BOTAN_XMSS_WOTS_ADDRESSED_PRIVATEKEY_H__
+#define BOTAN_XMSS_WOTS_ADDRESSED_PRIVATEKEY_H__
+
+#include <botan/xmss_address.h>
+#include <botan/internal/xmss_wots_addressed_publickey.h>
+#include <botan/xmss_wots_privatekey.h>
+
+namespace Botan {
+
+/**
+ * Wrapper class to pair an XMSS_WOTS_PrivateKey with an XMSS Address. Since
+ * the PK_Ops::Signature interface does not allow an extra address
+ * parameter to be passed to the sign(RandomNumberGenerator&), the address
+ * needs to be stored together with the key and passed to the
+ * XMSS_WOTS_Signature_Operation() on creation.
+ **/
+class XMSS_WOTS_Addressed_PrivateKey
+ : public virtual XMSS_WOTS_Addressed_PublicKey,
+ public virtual Private_Key
+ {
+ public:
+ XMSS_WOTS_Addressed_PrivateKey(const XMSS_WOTS_PrivateKey& private_key)
+ : XMSS_WOTS_Addressed_PublicKey(private_key),
+ m_priv_key(private_key) {}
+
+ XMSS_WOTS_Addressed_PrivateKey(const XMSS_WOTS_PrivateKey& private_key,
+ const XMSS_Address& adrs)
+ : XMSS_WOTS_Addressed_PublicKey(private_key, adrs),
+ m_priv_key(private_key) {}
+
+ XMSS_WOTS_Addressed_PrivateKey(XMSS_WOTS_PrivateKey&& private_key)
+ : XMSS_WOTS_Addressed_PublicKey(XMSS_WOTS_PublicKey(private_key)),
+ m_priv_key(std::move(private_key)) {}
+
+ XMSS_WOTS_Addressed_PrivateKey(XMSS_WOTS_PrivateKey&& private_key,
+ XMSS_Address&& adrs)
+ : XMSS_WOTS_Addressed_PublicKey(XMSS_WOTS_PublicKey(private_key),
+ std::move(adrs)),
+ m_priv_key(std::move(private_key)) {}
+
+ const XMSS_WOTS_PrivateKey& private_key() const { return m_priv_key; }
+ XMSS_WOTS_PrivateKey& private_key() { return m_priv_key; }
+
+ virtual AlgorithmIdentifier
+ pkcs8_algorithm_identifier() const override
+ {
+ return m_priv_key.pkcs8_algorithm_identifier();
+ }
+
+ virtual secure_vector<byte> pkcs8_private_key() const override
+ {
+ return m_priv_key.pkcs8_private_key();
+ }
+
+ private:
+ XMSS_WOTS_PrivateKey m_priv_key;
+ };
+
+}
+
+#endif
diff --git a/src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h b/src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h
new file mode 100644
index 000000000..52165684f
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h
@@ -0,0 +1,107 @@
+/**
+ * XMSS WOTS Addressed Public Key
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+
+#ifndef BOTAN_XMSS_WOTS_ADDRESSED_PUBLICKEY_H__
+#define BOTAN_XMSS_WOTS_ADDRESSED_PUBLICKEY_H__
+
+#include <botan/xmss_address.h>
+#include <botan/xmss_wots_publickey.h>
+
+namespace Botan {
+
+/**
+ * Wrapper class to pair a XMSS_WOTS_PublicKey with an XMSS Address. Since
+ * the PK_Ops::Verification interface does not allow an extra address
+ * parameter to be passed to the sign(RandomNumberGenerator&), the address
+ * needs to be stored together with the key and passed to the
+ * XMSS_WOTS_Verification_Operation() on creation.
+ **/
+class XMSS_WOTS_Addressed_PublicKey : public virtual Public_Key
+ {
+ public:
+ XMSS_WOTS_Addressed_PublicKey(const XMSS_WOTS_PublicKey& public_key)
+ : m_pub_key(public_key), m_adrs() {}
+
+ XMSS_WOTS_Addressed_PublicKey(const XMSS_WOTS_PublicKey& public_key,
+ const XMSS_Address& adrs)
+ : m_pub_key(public_key), m_adrs(adrs) {}
+
+ XMSS_WOTS_Addressed_PublicKey(XMSS_WOTS_PublicKey&& public_key)
+ : m_pub_key(std::move(public_key)), m_adrs() {}
+
+ XMSS_WOTS_Addressed_PublicKey(XMSS_WOTS_PublicKey&& public_key,
+ XMSS_Address&& adrs)
+ : m_pub_key(std::move(public_key)), m_adrs(std::move(adrs)) {}
+
+ const XMSS_WOTS_PublicKey& public_key() const { return m_pub_key; }
+ XMSS_WOTS_PublicKey& public_key() { return m_pub_key; }
+
+ const XMSS_Address& address() const { return m_adrs; }
+ XMSS_Address& address() { return m_adrs; }
+
+ virtual std::string algo_name() const override
+ {
+ return m_pub_key.algo_name();
+ }
+
+ virtual AlgorithmIdentifier algorithm_identifier() const override
+ {
+ return m_pub_key.algorithm_identifier();
+ }
+
+ virtual bool check_key(RandomNumberGenerator& rng,
+ bool strong) const override
+ {
+ return m_pub_key.check_key(rng, strong);
+ }
+
+ virtual std::unique_ptr<PK_Ops::Verification>
+ create_verification_op(const std::string& params,
+ const std::string& provider) const override
+ {
+ return m_pub_key.create_verification_op(params, provider);
+ }
+
+ virtual OID get_oid() const override
+ {
+ return m_pub_key.get_oid();
+ }
+
+ virtual size_t estimated_strength() const override
+ {
+ return m_pub_key.estimated_strength();
+ }
+
+ virtual size_t max_input_bits() const override
+ {
+ return m_pub_key.max_input_bits();
+ }
+
+ virtual size_t message_part_size() const override
+ {
+ return m_pub_key.message_part_size();
+ }
+
+ virtual size_t message_parts() const override
+ {
+ return m_pub_key.message_parts();
+ }
+
+ virtual std::vector<byte> x509_subject_public_key() const override
+ {
+ return m_pub_key.x509_subject_public_key();
+ }
+
+ protected:
+ XMSS_WOTS_PublicKey m_pub_key;
+ XMSS_Address m_adrs;
+ };
+
+}
+
+#endif
diff --git a/src/lib/pubkey/xmss/xmss_wots_common_ops.cpp b/src/lib/pubkey/xmss/xmss_wots_common_ops.cpp
new file mode 100644
index 000000000..5d0349677
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_common_ops.cpp
@@ -0,0 +1,40 @@
+/**
+ * XMSS WOTS Common Ops
+ * Operations shared by XMSS WOTS signature generation and verification
+ * operations.
+ *
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#include <botan/internal/xmss_wots_common_ops.h>
+
+namespace Botan {
+
+void
+XMSS_WOTS_Common_Ops::chain(secure_vector<byte>& result,
+ size_t start_idx,
+ size_t steps,
+ XMSS_Address& adrs,
+ const secure_vector<byte>& seed)
+ {
+ for(size_t i = start_idx;
+ i < (start_idx + steps) && i < m_wots_params.wots_parameter();
+ i++)
+ {
+ adrs.set_hash_address(i);
+
+ //Calculate tmp XOR bitmask
+ adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Mask_Mode);
+ xor_buf(result, m_hash.prf(seed, adrs.bytes()), result.size());
+
+ // Calculate key
+ adrs.set_key_mask_mode(XMSS_Address::Key_Mask::Key_Mode);
+
+ //Calculate f(key, tmp XOR bitmask)
+ m_hash.f(result, m_hash.prf(seed, adrs.bytes()), result);
+ }
+ }
+
+}
diff --git a/src/lib/pubkey/xmss/xmss_wots_common_ops.h b/src/lib/pubkey/xmss/xmss_wots_common_ops.h
new file mode 100644
index 000000000..f3153515c
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_common_ops.h
@@ -0,0 +1,55 @@
+/**
+ * XMSS WOTS Common Operations
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#ifndef BOTAN_XMSS_WOTS_COMMON_OPS_H__
+#define BOTAN_XMSS_WOTS_COMMON_OPS_H__
+
+#include <cstddef>
+#include <botan/types.h>
+#include <botan/xmss_wots_parameters.h>
+#include <botan/xmss_address.h>
+#include <botan/xmss_hash.h>
+
+namespace Botan {
+
+/**
+ * Operations shared by XMSS WOTS signature generation and verification
+ * operations.
+ **/
+class XMSS_WOTS_Common_Ops
+ {
+ public:
+ XMSS_WOTS_Common_Ops(XMSS_WOTS_Parameters::ots_algorithm_t oid)
+ : m_wots_params(oid), m_hash(m_wots_params.hash_function_name()) {}
+
+
+ protected:
+ /**
+ * Algorithm 2: Chaining Function.
+ *
+ * @param[out] result Contains the n-byte input string "x" upon call to chain(),
+ * that will be replaced with the value obtained by iterating
+ * the cryptographic hash function "F" steps times on the
+ * input x using the outputs of the PRNG "G".
+ * @param[in] start_idx The start index.
+ * @param[in] steps A number of steps.
+ * @param[in] adrs An OTS Hash Address.
+ * @param[in] seed A Seed.
+ **/
+ void chain(secure_vector<byte>& result,
+ size_t start_idx,
+ size_t steps,
+ XMSS_Address& adrs,
+ const secure_vector<byte>& seed);
+
+ XMSS_WOTS_Parameters m_wots_params;
+ XMSS_Hash m_hash;
+ };
+
+}
+
+#endif
diff --git a/src/lib/pubkey/xmss/xmss_wots_privatekey.cpp b/src/lib/pubkey/xmss/xmss_wots_privatekey.cpp
index 1a68b187d..13568e0b9 100644
--- a/src/lib/pubkey/xmss/xmss_wots_privatekey.cpp
+++ b/src/lib/pubkey/xmss/xmss_wots_privatekey.cpp
@@ -8,6 +8,7 @@
* Botan is released under the Simplified BSD License (see license.txt)
**/
+#include <botan/internal/xmss_wots_signature_operation.h>
#include <botan/xmss_wots_privatekey.h>
namespace Botan {
@@ -77,4 +78,16 @@ XMSS_WOTS_PrivateKey::sign(
return sig;
}
+std::unique_ptr<PK_Ops::Signature>
+XMSS_WOTS_PrivateKey::create_signature_op(RandomNumberGenerator&,
+ const std::string&,
+ const std::string& provider) const
+ {
+ if(provider == "base" || provider.empty())
+ return std::unique_ptr<PK_Ops::Signature>(
+ new XMSS_WOTS_Signature_Operation(*this));
+
+ throw Provider_Not_Found(algo_name(), provider);
+ }
+
}
diff --git a/src/lib/pubkey/xmss/xmss_wots_privatekey.h b/src/lib/pubkey/xmss/xmss_wots_privatekey.h
index 1a6e50fe8..312db8b7b 100644
--- a/src/lib/pubkey/xmss/xmss_wots_privatekey.h
+++ b/src/lib/pubkey/xmss/xmss_wots_privatekey.h
@@ -234,10 +234,7 @@ class BOTAN_DLL XMSS_WOTS_PrivateKey : public virtual XMSS_WOTS_PublicKey,
virtual std::unique_ptr<PK_Ops::Signature>
create_signature_op(RandomNumberGenerator&,
const std::string&,
- const std::string&) const override
- {
- BOTAN_ASSERT(false, "XMSS_WOTS_Signature_Operation not available.");
- }
+ const std::string& provider) const override;
virtual secure_vector<byte> pkcs8_private_key() const override
{
diff --git a/src/lib/pubkey/xmss/xmss_wots_publickey.cpp b/src/lib/pubkey/xmss/xmss_wots_publickey.cpp
index aa0240be8..9a7df1682 100644
--- a/src/lib/pubkey/xmss/xmss_wots_publickey.cpp
+++ b/src/lib/pubkey/xmss/xmss_wots_publickey.cpp
@@ -8,6 +8,7 @@
* Botan is released under the Simplified BSD License (see license.txt)
**/
+#include <botan/internal/xmss_wots_verification_operation.h>
#include <botan/xmss_wots_publickey.h>
namespace Botan {
@@ -63,4 +64,16 @@ XMSS_WOTS_PublicKey::pub_key_from_signature(const secure_vector<byte>& msg,
return result;
}
+std::unique_ptr<PK_Ops::Verification>
+XMSS_WOTS_PublicKey::create_verification_op(const std::string&,
+ const std::string& provider) const
+ {
+ if(provider == "base" || provider.empty())
+ {
+ return std::unique_ptr<PK_Ops::Verification>(
+ new XMSS_WOTS_Verification_Operation(*this));
+ }
+ throw Provider_Not_Found(algo_name(), provider);
+ }
+
}
diff --git a/src/lib/pubkey/xmss/xmss_wots_publickey.h b/src/lib/pubkey/xmss/xmss_wots_publickey.h
index a3e5232e8..9efb04667 100644
--- a/src/lib/pubkey/xmss/xmss_wots_publickey.h
+++ b/src/lib/pubkey/xmss/xmss_wots_publickey.h
@@ -243,10 +243,7 @@ class BOTAN_DLL XMSS_WOTS_PublicKey : virtual public Public_Key
virtual std::unique_ptr<PK_Ops::Verification>
create_verification_op(const std::string&,
- const std::string&) const override
- {
- BOTAN_ASSERT(false, "XMSS_WOTS_Verification_Operation not available.");
- }
+ const std::string& provider) const override;
virtual size_t estimated_strength() const override
{
diff --git a/src/lib/pubkey/xmss/xmss_wots_signature_operation.cpp b/src/lib/pubkey/xmss/xmss_wots_signature_operation.cpp
new file mode 100644
index 000000000..82f32b88e
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_signature_operation.cpp
@@ -0,0 +1,52 @@
+/**
+ * XMSS WOTS Signature Operation
+ * Signature generation operation for Winternitz One Time Signatures for use
+ * in Extended Hash-Based Signatures (XMSS).
+ *
+ * This operation is not intended for stand-alone use and thus not registered
+ * in the Botan algorithm registry.
+ *
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#include <botan/internal/xmss_wots_signature_operation.h>
+
+namespace Botan {
+
+XMSS_WOTS_Signature_Operation::XMSS_WOTS_Signature_Operation(
+ const XMSS_WOTS_Addressed_PrivateKey& private_key)
+ : XMSS_WOTS_Common_Ops(private_key.private_key().wots_parameters().oid()),
+ m_priv_key(private_key),
+ m_msg_buf(0)
+ {
+ m_msg_buf.reserve(m_priv_key.message_part_size());
+ }
+
+void
+XMSS_WOTS_Signature_Operation::update(const byte msg[], size_t msg_len)
+ {
+ BOTAN_ASSERT(msg_len == message_part_size() &&
+ m_msg_buf.size() == 0,
+ "XMSS WOTS only supports one message part of size n.");
+
+ for(size_t i = 0; i < msg_len; i++)
+ m_msg_buf.push_back(msg[i]);
+ }
+
+secure_vector<byte>
+XMSS_WOTS_Signature_Operation::sign(RandomNumberGenerator&)
+ {
+ secure_vector<byte> result(0);
+ result.reserve(m_wots_params.len() * m_wots_params.element_size());
+ XMSS_WOTS_PrivateKey& priv_key = m_priv_key.private_key();
+ for(const auto& node : priv_key.sign(m_msg_buf, m_priv_key.address()))
+ {
+ std::copy(node.begin(), node.end(), std::back_inserter(result));
+ }
+
+ return result;
+ }
+
+}
diff --git a/src/lib/pubkey/xmss/xmss_wots_signature_operation.h b/src/lib/pubkey/xmss/xmss_wots_signature_operation.h
new file mode 100644
index 000000000..2b469e200
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_signature_operation.h
@@ -0,0 +1,74 @@
+/**
+ * XMSS WOTS Signature Operation
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#ifndef BOTAN_XMSS_WOTS_SIGNATURE_OPERATION_H__
+#define BOTAN_XMSS_WOTS_SIGNATURE_OPERATION_H__
+
+#include <cstddef>
+#include <iterator>
+#include <botan/assert.h>
+#include <botan/types.h>
+#include <botan/internal/pk_ops.h>
+#include <botan/internal/xmss_wots_addressed_privatekey.h>
+#include <botan/internal/xmss_wots_common_ops.h>
+
+namespace Botan {
+
+/**
+ * Signature generation operation for Winternitz One Time Signatures for use
+ * in Extended Hash-Based Signatures (XMSS).
+ *
+ * This operation is not intended for stand-alone use and thus not registered
+ * in the Botan algorithm registry.
+ ***/
+class XMSS_WOTS_Signature_Operation : public virtual PK_Ops::Signature,
+ public XMSS_WOTS_Common_Ops
+ {
+ public:
+ typedef XMSS_WOTS_Addressed_PrivateKey Key_Type;
+
+ XMSS_WOTS_Signature_Operation(
+ const XMSS_WOTS_Addressed_PrivateKey& private_key);
+
+ virtual ~XMSS_WOTS_Signature_Operation() {}
+
+ virtual size_t message_part_size() const override
+ {
+ return m_priv_key.message_part_size();
+ }
+
+ virtual size_t message_parts() const override
+ {
+ return m_priv_key.message_parts();
+ }
+
+ /**
+ * Creates a XMSS WOTS signature for the message provided through call
+ * to update(). XMSS wots only supports one message part and a fixed
+ * message size of "n" bytes where "n" equals the element size of
+ * the chosen XMSS WOTS signature method. The random number generator
+ * argument is supplied for interface compatibility and remains unused.
+ *
+ * @return serialized Winternitz One Time Signature.
+ **/
+ secure_vector<byte> sign(RandomNumberGenerator&) override;
+
+ void update(const byte msg[], size_t msg_len) override;
+
+ private:
+ wots_keysig_t sign(const secure_vector<byte>& msg,
+ const wots_keysig_t& priv_key,
+ XMSS_Address& adrs,
+ const secure_vector<byte>& seed);
+ XMSS_WOTS_Addressed_PrivateKey m_priv_key;
+ secure_vector<byte> m_msg_buf;
+ };
+
+}
+
+#endif
+
diff --git a/src/lib/pubkey/xmss/xmss_wots_verification_operation.cpp b/src/lib/pubkey/xmss/xmss_wots_verification_operation.cpp
new file mode 100644
index 000000000..6bff05b93
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_verification_operation.cpp
@@ -0,0 +1,68 @@
+/**
+ * XMSS WOTS Verification Operation
+ * Provides signature verification capabilities for Winternitz One Time
+ * Signatures used in Extended Hash-Based Signatures (XMSS).
+ *
+ * This operation is not intended for stand-alone use and thus not registered
+ * in the Botan algorithm registry.
+ *
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#include <botan/internal/xmss_wots_verification_operation.h>
+
+namespace Botan {
+
+XMSS_WOTS_Verification_Operation::XMSS_WOTS_Verification_Operation(
+ const XMSS_WOTS_Addressed_PublicKey& public_key)
+ : XMSS_WOTS_Common_Ops(public_key.public_key().wots_parameters().oid()),
+ m_pub_key(public_key),
+ m_msg_buf(0)
+ {
+ m_msg_buf.reserve(m_pub_key.message_part_size());
+ }
+
+void
+XMSS_WOTS_Verification_Operation::update(const byte msg[], size_t msg_len)
+ {
+ BOTAN_ASSERT(msg_len == message_part_size() &&
+ m_msg_buf.size() == 0,
+ "XMSS WOTS only supports one message part of size n.");
+
+ for(size_t i = 0; i < msg_len; i++)
+ m_msg_buf.push_back(msg[i]);
+ }
+
+bool XMSS_WOTS_Verification_Operation::is_valid_signature(const byte sig[],
+ size_t sig_len)
+ {
+ const XMSS_WOTS_Parameters& w = m_pub_key.public_key().wots_parameters();
+
+ BOTAN_ASSERT(sig_len == w.element_size() * w.len(),
+ "Invalid signature size.");
+
+ wots_keysig_t signature(0);
+ signature.reserve(sig_len);
+
+ size_t begin = 0;
+ size_t end = 0;
+ while(signature.size() < w.len())
+ {
+ begin = end;
+ end = begin + w.element_size();
+ signature.push_back(secure_vector<byte>(sig + begin, sig + end));
+ }
+
+ XMSS_WOTS_PublicKey pubkey_msg(w.oid(),
+ m_msg_buf,
+ signature,
+ m_pub_key.address(),
+ m_pub_key.public_key().public_seed());
+
+ return pubkey_msg.key_data() == m_pub_key.public_key().key_data();
+ }
+
+}
+
diff --git a/src/lib/pubkey/xmss/xmss_wots_verification_operation.h b/src/lib/pubkey/xmss/xmss_wots_verification_operation.h
new file mode 100644
index 000000000..d4d961e80
--- /dev/null
+++ b/src/lib/pubkey/xmss/xmss_wots_verification_operation.h
@@ -0,0 +1,66 @@
+/**
+ * XMSS_WOTS_Verification_Operation.h
+ * (C) 2016 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#ifndef BOTAN_XMSS_WOTS_VERIFICATION_OPERATION_H__
+#define BOTAN_XMSS_WOTS_VERIFICATION_OPERATION_H__
+
+#include <cstddef>
+#include <iterator>
+#include <botan/types.h>
+#include <botan/internal/pk_ops.h>
+#include <botan/internal/xmss_wots_addressed_publickey.h>
+#include <botan/internal/xmss_wots_common_ops.h>
+
+namespace Botan {
+
+/**
+ * Provides signature verification capabilities for Winternitz One Time
+ * Signatures used in Extended Merkle Tree Signatures (XMSS).
+ *
+ * This operation is not intended for stand-alone use and thus not registered
+ * in the Botan algorithm registry.
+ **/
+class XMSS_WOTS_Verification_Operation
+ : public virtual PK_Ops::Verification,
+ public XMSS_WOTS_Common_Ops
+ {
+ public:
+ typedef XMSS_WOTS_Addressed_PublicKey Key_Type;
+
+ XMSS_WOTS_Verification_Operation(
+ const XMSS_WOTS_Addressed_PublicKey& public_key);
+
+ virtual ~XMSS_WOTS_Verification_Operation() {}
+
+ virtual size_t max_input_bits() const override
+ {
+ return m_pub_key.max_input_bits();
+ }
+
+ virtual size_t message_part_size() const override
+ {
+ return m_pub_key.message_part_size();
+ }
+
+ virtual size_t message_parts() const override
+ {
+ return m_pub_key.message_parts();
+ }
+
+ virtual bool is_valid_signature(const byte sig[],
+ size_t sig_len) override;
+
+ void update(const byte msg[], size_t msg_len) override;
+
+ private:
+ XMSS_WOTS_Addressed_PublicKey m_pub_key;
+ secure_vector<byte> m_msg_buf;
+ };
+
+}
+
+#endif