diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/pubkey/xmss/info.txt | 8 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_signature_operation.cpp | 2 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_tools.h | 8 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_verification_operation.cpp | 4 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_addressed_privatekey.h | 68 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h | 97 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_common_ops.cpp | 40 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_common_ops.h | 55 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_privatekey.cpp | 13 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_privatekey.h | 33 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_publickey.cpp | 13 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_publickey.h | 28 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_signature_operation.cpp | 54 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_signature_operation.h | 62 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_verification_operation.cpp | 72 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_wots_verification_operation.h | 49 |
16 files changed, 563 insertions, 43 deletions
diff --git a/src/lib/pubkey/xmss/info.txt b/src/lib/pubkey/xmss/info.txt index 862ff68f9..93fe4eef5 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_signature_operation.cpp b/src/lib/pubkey/xmss/xmss_signature_operation.cpp index 9418e3385..80b9c4746 100644 --- a/src/lib/pubkey/xmss/xmss_signature_operation.cpp +++ b/src/lib/pubkey/xmss/xmss_signature_operation.cpp @@ -101,7 +101,7 @@ void XMSS_Signature_Operation::initialize() m_randomness = m_hash.prf(m_priv_key.prf(), index_bytes); index_bytes.clear(); XMSS_Tools::concat(index_bytes, m_leaf_idx, - m_priv_key.xmss_parameters().element_size()); + m_priv_key.xmss_parameters().element_size()); m_hash.h_msg_init(m_randomness, m_priv_key.root(), index_bytes); diff --git a/src/lib/pubkey/xmss/xmss_tools.h b/src/lib/pubkey/xmss/xmss_tools.h index 6f85c5818..66eaf28e2 100644 --- a/src/lib/pubkey/xmss/xmss_tools.h +++ b/src/lib/pubkey/xmss/xmss_tools.h @@ -64,13 +64,17 @@ void XMSS_Tools::concat(secure_vector<byte>& target, const T& src) { const byte* src_bytes = reinterpret_cast<const byte*>(&src); if(CPUID::is_little_endian()) + { std::reverse_copy(src_bytes, src_bytes + sizeof(src), std::back_inserter(target)); + } else + { std::copy(src_bytes, src_bytes + sizeof(src), std::back_inserter(target)); + } } @@ -87,13 +91,17 @@ void XMSS_Tools::concat(secure_vector<byte>& target, const byte* src_bytes = reinterpret_cast<const byte*>(&src); if(CPUID::is_little_endian()) + { std::reverse_copy(src_bytes, src_bytes + c, std::back_inserter(target)); + } else + { std::copy(src_bytes + sizeof(src) - c, src_bytes + sizeof(src), std::back_inserter(target)); + } } } diff --git a/src/lib/pubkey/xmss/xmss_verification_operation.cpp b/src/lib/pubkey/xmss/xmss_verification_operation.cpp index 4a9c5aa11..34d7ee647 100644 --- a/src/lib/pubkey/xmss/xmss_verification_operation.cpp +++ b/src/lib/pubkey/xmss/xmss_verification_operation.cpp @@ -78,8 +78,8 @@ XMSS_Verification_Operation::verify(const XMSS_Signature& sig, XMSS_Address adrs; secure_vector<byte> index_bytes; XMSS_Tools::concat(index_bytes, - sig.unused_leaf_index(), - m_xmss_params.element_size()); + sig.unused_leaf_index(), + m_xmss_params.element_size()); secure_vector<byte> msg_digest = m_hash.h_msg(sig.randomness(), public_key.root(), 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..a07b0b803 --- /dev/null +++ b/src/lib/pubkey/xmss/xmss_wots_addressed_publickey.h @@ -0,0 +1,97 @@ +/** + * 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 key_length() const override + { + return m_pub_key.estimated_strength(); + } + + 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 02a3934f5..e3f4cab94 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 71e87ef48..158bad1bb 100644 --- a/src/lib/pubkey/xmss/xmss_wots_privatekey.h +++ b/src/lib/pubkey/xmss/xmss_wots_privatekey.h @@ -12,6 +12,7 @@ #include <memory> #include <botan/alg_id.h> #include <botan/assert.h> +#include <botan/exceptn.h> #include <botan/pk_keys.h> #include <botan/types.h> #include <botan/xmss_wots_parameters.h> @@ -150,8 +151,7 @@ class BOTAN_DLL XMSS_WOTS_PrivateKey : public virtual XMSS_WOTS_PublicKey, * * @return A XMSS_WOTS_PublicKey. **/ - XMSS_WOTS_PublicKey generate_public_key( - XMSS_Address& adrs); + XMSS_WOTS_PublicKey generate_public_key(XMSS_Address& adrs); /** * Algorithm 4: "WOTS_genPK" @@ -165,10 +165,9 @@ class BOTAN_DLL XMSS_WOTS_PrivateKey : public virtual XMSS_WOTS_PublicKey, * @param adrs Hash function address encoding the address of * the WOTS+ key pair within a greater structure. **/ - void generate_public_key( - XMSS_WOTS_PublicKey& pub_key, - wots_keysig_t&& in_key_data, - XMSS_Address& adrs); + void generate_public_key(XMSS_WOTS_PublicKey& pub_key, + wots_keysig_t&& in_key_data, + XMSS_Address& adrs); /** * Algorithm 5: "WOTS_sign" @@ -180,9 +179,8 @@ class BOTAN_DLL XMSS_WOTS_PrivateKey : public virtual XMSS_WOTS_PublicKey, * * @return signature for msg. **/ - wots_keysig_t sign( - const secure_vector<byte>& msg, - XMSS_Address& adrs); + wots_keysig_t sign(const secure_vector<byte>& msg, + XMSS_Address& adrs); /** * Retrieves the secret seed used to generate WOTS+ chains. The seed @@ -195,14 +193,6 @@ class BOTAN_DLL XMSS_WOTS_PrivateKey : public virtual XMSS_WOTS_PublicKey, return m_private_seed; } - ///** - // * Retrieves the secret seed used to generate WOTS+ chains. The seed - // * should be a uniformly random n-byte value. - // * - // * @return secret seed. - // **/ - //secure_vector<byte>& private_seed() { return m_private_seed; } - /** * Sets the secret seed used to generate WOTS+ chains. The seed * should be a uniformly random n-byte value. @@ -228,20 +218,17 @@ class BOTAN_DLL XMSS_WOTS_PrivateKey : public virtual XMSS_WOTS_PublicKey, virtual AlgorithmIdentifier pkcs8_algorithm_identifier() const override { - BOTAN_ASSERT(false, "No AlgorithmIdentifier available for XMSS-WOTS."); + throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS."); } 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 { - BOTAN_ASSERT(false, "No PKCS8 key format defined for XMSS-WOTS."); + throw Not_Implemented("No PKCS8 key format defined for XMSS-WOTS."); } private: diff --git a/src/lib/pubkey/xmss/xmss_wots_publickey.cpp b/src/lib/pubkey/xmss/xmss_wots_publickey.cpp index 3726fcc59..0eea59ea3 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 394824d0a..afb0ac847 100644 --- a/src/lib/pubkey/xmss/xmss_wots_publickey.h +++ b/src/lib/pubkey/xmss/xmss_wots_publickey.h @@ -14,6 +14,7 @@ #include <botan/alg_id.h> #include <botan/asn1_oid.h> #include <botan/assert.h> +#include <botan/exceptn.h> #include <botan/pk_keys.h> #include <botan/types.h> #include <botan/xmss_wots_parameters.h> @@ -199,22 +200,28 @@ class BOTAN_DLL XMSS_WOTS_PublicKey : virtual public Public_Key operator wots_keysig_t& () { return m_key; } const secure_vector<byte>& public_seed() const { return m_public_seed; } + secure_vector<byte>& public_seed() { return m_public_seed; } + void set_public_seed(const secure_vector<byte>& public_seed) { m_public_seed = public_seed; } + void set_public_seed(secure_vector<byte>&& public_seed) { m_public_seed = std::move(public_seed); } const wots_keysig_t& key_data() const { return m_key; } + wots_keysig_t& key_data() { return m_key; } + void set_key_data(const wots_keysig_t& key_data) { m_key = key_data; } + void set_key_data(wots_keysig_t&& key_data) { m_key = std::move(key_data); @@ -232,20 +239,17 @@ class BOTAN_DLL XMSS_WOTS_PublicKey : virtual public Public_Key virtual AlgorithmIdentifier algorithm_identifier() const override { - BOTAN_ASSERT(false, "No AlgorithmIdentifier available for XMSS-WOTS."); + throw Not_Implemented("No AlgorithmIdentifier available for XMSS-WOTS."); } virtual bool check_key(RandomNumberGenerator&, bool) const override { - BOTAN_ASSERT(false, "No key strength check implemented for XMSS-WOTS."); + return true; } 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 { @@ -257,19 +261,9 @@ class BOTAN_DLL XMSS_WOTS_PublicKey : virtual public Public_Key return m_wots_params.estimated_strength(); } - virtual size_t message_part_size() const override - { - return m_wots_params.element_size(); - } - - virtual size_t message_parts() const override - { - return 1; - } - virtual std::vector<byte> x509_subject_public_key() const override { - BOTAN_ASSERT(false, "No x509 key format defined for XMSS-WOTS."); + throw Not_Implemented("No x509 key format defined for XMSS-WOTS."); } bool operator==(const XMSS_WOTS_PublicKey& key) 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..532e4d782 --- /dev/null +++ b/src/lib/pubkey/xmss/xmss_wots_signature_operation.cpp @@ -0,0 +1,54 @@ +/** + * 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.private_key().wots_parameters().element_size()); + } + +void +XMSS_WOTS_Signature_Operation::update(const byte msg[], size_t msg_len) + { + BOTAN_ASSERT(msg_len == m_priv_key.private_key().wots_parameters(). + element_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..69ba6b4fe --- /dev/null +++ b/src/lib/pubkey/xmss/xmss_wots_signature_operation.h @@ -0,0 +1,62 @@ +/** + * 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: + XMSS_WOTS_Signature_Operation( + const XMSS_WOTS_Addressed_PrivateKey& private_key); + + virtual ~XMSS_WOTS_Signature_Operation() {} + + /** + * 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..d66c508bb --- /dev/null +++ b/src/lib/pubkey/xmss/xmss_wots_verification_operation.cpp @@ -0,0 +1,72 @@ +/** + * 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.public_key().wots_parameters(). + element_size()); + } + +void +XMSS_WOTS_Verification_Operation::update(const byte msg[], size_t msg_len) + { + BOTAN_ASSERT(msg_len == m_pub_key.public_key().wots_parameters(). + element_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..1125a6af8 --- /dev/null +++ b/src/lib/pubkey/xmss/xmss_wots_verification_operation.h @@ -0,0 +1,49 @@ +/** + * 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: + XMSS_WOTS_Verification_Operation( + const XMSS_WOTS_Addressed_PublicKey& public_key); + + virtual ~XMSS_WOTS_Verification_Operation() {} + + 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 |