Skip to content

Commit

Permalink
Merge GH #1858 Update XMSS to conform to RFC 8391
Browse files Browse the repository at this point in the history
  • Loading branch information
randombit committed May 24, 2019
2 parents 0224ebc + e390adc commit 7de8754
Show file tree
Hide file tree
Showing 21 changed files with 2,520 additions and 624 deletions.
45 changes: 26 additions & 19 deletions doc/manual/pubkey.rst
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ loaded key. If the key check fails a respective error is thrown.
#include <botan/x509cert.h>
#include <botan/auto_rng.h>
#include <botan/rng.h>
int main()
{
Botan::X509_Certificate cert("cert.pem");
Expand Down Expand Up @@ -841,36 +841,43 @@ using ``botan speed McEliece``
eXtended Merkle Signature Scheme (XMSS)
----------------------------------------

Botan implements the single tree version of the eXtended Merkle Signature
Botan implements the single tree version of the eXtended Merkle Signature
Scheme (XMSS) using Winternitz One Time Signatures+ (WOTS+). The implementation
is based on IETF Internet-Draft "XMSS: Extended Hash-Based Signatures".
is based on RFC 8391 "XMSS: eXtended Merkle Signature Scheme", available at
https://datatracker.ietf.org/doc/rfc8391/.

XMSS uses the Botan interfaces for public key cryptography.
The following algorithms are implemented:

1. XMSS_SHA2-256_W16_H10
#. XMSS_SHA2-256_W16_H16
#. XMSS_SHA2-256_W16_H20
#. XMSS_SHA2-512_W16_H10
#. XMSS_SHA2-512_W16_H16
#. XMSS_SHA2-512_W16_H20
#. XMSS_SHAKE128_W16_H10
#. XMSS_SHAKE128_W16_H10
#. XMSS_SHAKE128_W16_H10
#. XMSS_SHAKE256_W16_H10
#. XMSS_SHAKE256_W16_H10
#. XMSS_SHAKE256_W16_H10

1. XMSS-SHA2_10_256
# XMSS-SHA2_16_256
# XMSS-SHA2_20_256
# XMSS-SHA2_10_512
# XMSS-SHA2_16_512
# XMSS-SHA2_20_512
# XMSS-SHAKE_10_256
# XMSS-SHAKE_16_256
# XMSS-SHAKE_20_256
# XMSS-SHAKE_10_512
# XMSS-SHAKE_16_512
# XMSS-SHAKE_20_512

The algorithm name contains the hash function name, tree height and digest
width defined by the corresponding parameter set. Choosing `XMSS-SHA2_10_256`
for instance will use the SHA2-256 hash function to generate a tree of height
ten.

Code Example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following code snippet shows a minimum example on how to create an XMSS
public/private key pair and how to use these keys to create and verify a signature:
public/private key pair and how to use these keys to create and verify a
signature:

.. code-block:: cpp
#include <botan/botan.h>
#include <iostream>
#include <botan/secmem.h>
#include <botan/auto_rng.h>
#include <botan/xmss.h>
Expand All @@ -882,7 +889,7 @@ public/private key pair and how to use these keys to create and verify a signatu
// create a new public/private key pair using SHA2 256 as hash
// function and a tree height of 10.
Botan::XMSS_PrivateKey private_key(
Botan::XMSS_Parameters::xmss_algorithm_t::XMSS_SHA2_256_W16_H10,
Botan::XMSS_Parameters::xmss_algorithm_t::XMSS_SHA2_10_256,
rng);
Botan::XMSS_PublicKey public_key(private_key);
Expand Down
8 changes: 4 additions & 4 deletions src/cli/speed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2087,10 +2087,10 @@ class Speed final : public Command
*/
std::vector<std::string> xmss_params
{
"XMSS_SHA2-256_W16_H10",
"XMSS_SHA2-512_W16_H10",
"XMSS_SHAKE128_W16_H10",
"XMSS_SHAKE256_W16_H10",
"XMSS-SHA2_10_256",
"XMSS-SHAKE_10_256",
"XMSS-SHA2_10_512",
"XMSS-SHAKE_10_512",
};

for(std::string params : xmss_params)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/pubkey/pk_algs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ create_private_key(const std::string& alg_name,
if(alg_name == "XMSS")
{
return std::unique_ptr<Private_Key>(
new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS_SHA2-512_W16_H10" : params).oid(), rng));
new XMSS_PrivateKey(XMSS_Parameters(params.empty() ? "XMSS-SHA2_10_512" : params).oid(), rng));
}
#endif

Expand Down
8 changes: 4 additions & 4 deletions src/lib/pubkey/xmss/xmss.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
*
* <pre>
* [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
* Request for Comments: 8391
* Release: May 2018.
* https://datatracker.ietf.org/doc/rfc8391/
* </pre>
*
* (C) 2016,2017 Matthias Gierlings
* (C) 2016,2017,2018 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
**/
Expand Down
129 changes: 64 additions & 65 deletions src/lib/pubkey/xmss/xmss_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
* XMSS Parameters
* Descibes a signature method for XMSS, 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
* Request for Comments: 8391
* Release: May 2018.
* https://datatracker.ietf.org/doc/rfc8391/
*
* (C) 2016,2017 Matthias Gierlings
* (C) 2016,2017,2018 Matthias Gierlings
*
* Botan is released under the Simplified BSD License (see license.txt)
**/
Expand All @@ -19,30 +18,30 @@ namespace Botan {

XMSS_Parameters::xmss_algorithm_t XMSS_Parameters::xmss_id_from_string(const std::string& param_set)
{
if(param_set == "XMSS_SHA2-256_W16_H10")
{ return XMSS_SHA2_256_W16_H10; }
if(param_set == "XMSS_SHA2-256_W16_H16")
{ return XMSS_SHA2_256_W16_H16; }
if(param_set == "XMSS_SHA2-256_W16_H20")
{ return XMSS_SHA2_256_W16_H20; }
if(param_set == "XMSS_SHA2-512_W16_H10")
{ return XMSS_SHA2_512_W16_H10; }
if(param_set == "XMSS_SHA2-512_W16_H16")
{ return XMSS_SHA2_512_W16_H16; }
if(param_set == "XMSS_SHA2-512_W16_H20")
{ return XMSS_SHA2_512_W16_H20; }
if(param_set == "XMSS_SHAKE128_W16_H10")
{ return XMSS_SHAKE128_W16_H10; }
if(param_set == "XMSS_SHAKE128_W16_H16")
{ return XMSS_SHAKE128_W16_H16; }
if(param_set == "XMSS_SHAKE128_W16_H20")
{ return XMSS_SHAKE128_W16_H20; }
if(param_set == "XMSS_SHAKE256_W16_H10")
{ return XMSS_SHAKE256_W16_H10; }
if(param_set == "XMSS_SHAKE256_W16_H16")
{ return XMSS_SHAKE256_W16_H16; }
if(param_set == "XMSS_SHAKE256_W16_H20")
{ return XMSS_SHAKE256_W16_H20; }
if(param_set == "XMSS-SHA2_10_256")
{ return XMSS_SHA2_10_256; }
if(param_set == "XMSS-SHA2_16_256")
{ return XMSS_SHA2_16_256; }
if(param_set == "XMSS-SHA2_20_256")
{ return XMSS_SHA2_20_256; }
if(param_set == "XMSS-SHA2_10_512")
{ return XMSS_SHA2_10_512; }
if(param_set == "XMSS-SHA2_16_512")
{ return XMSS_SHA2_16_512; }
if(param_set == "XMSS-SHA2_20_512")
{ return XMSS_SHA2_20_512; }
if(param_set == "XMSS-SHAKE_10_256")
{ return XMSS_SHAKE_10_256; }
if(param_set == "XMSS-SHAKE_10_256")
{ return XMSS_SHAKE_16_256; }
if(param_set == "XMSS-SHAKE_20_256")
{ return XMSS_SHAKE_20_256; }
if(param_set == "XMSS-SHAKE_10_512")
{ return XMSS_SHAKE_10_512; }
if(param_set == "XMSS-SHAKE_16_512")
{ return XMSS_SHAKE_16_512; }
if(param_set == "XMSS-SHAKE_20_512")
{ return XMSS_SHAKE_20_512; }
throw Lookup_Error("Unknown XMSS algorithm param '" + param_set + "'");
}

Expand All @@ -56,125 +55,125 @@ XMSS_Parameters::XMSS_Parameters(xmss_algorithm_t oid)
{
switch(oid)
{
case XMSS_SHA2_256_W16_H10:
case XMSS_SHA2_10_256:
m_element_size = 32;
m_w = 16;
m_len = 67;
m_tree_height = 10;
m_name = "XMSS_SHA2-256_W16_H10";
m_name = "XMSS-SHA2_10_256";
m_hash_name = "SHA-256";
m_strength = 256;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_256_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_256;
break;
case XMSS_SHA2_256_W16_H16:
case XMSS_SHA2_16_256:
m_element_size = 32;
m_w = 16;
m_len = 67;
m_tree_height = 16;
m_name = "XMSS_SHA2-256_W16_H16";
m_name = "XMSS-SHA2_16_256";
m_hash_name = "SHA-256";
m_strength = 256;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_256_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_256;
break;
case XMSS_SHA2_256_W16_H20:
case XMSS_SHA2_20_256:
m_element_size = 32;
m_w = 16;
m_len = 67;
m_tree_height = 20;
m_name = "XMSS_SHA2-256_W16_H20";
m_name = "XMSS-SHA2_20_256";
m_hash_name = "SHA-256";
m_strength = 256;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_256_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_256;
break;
case XMSS_SHA2_512_W16_H10:
case XMSS_SHA2_10_512:
m_element_size = 64;
m_w = 16;
m_len = 131;
m_tree_height = 10;
m_name = "XMSS_SHA2-512_W16_H10";
m_name = "XMSS-SHA2_10_512";
m_hash_name = "SHA-512";
m_strength = 512;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_512_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_512;
break;
case XMSS_SHA2_512_W16_H16:
case XMSS_SHA2_16_512:
m_element_size = 64;
m_w = 16;
m_len = 131;
m_tree_height = 16;
m_name = "XMSS_SHA2-512_W16_H16";
m_name = "XMSS-SHA2_16_512";
m_hash_name = "SHA-512";
m_strength = 512;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_512_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_512;
break;
case XMSS_SHA2_512_W16_H20:
case XMSS_SHA2_20_512:
m_element_size = 64;
m_w = 16;
m_len = 131;
m_tree_height = 20;
m_name = "XMSS_SHA2-512_W16_H20";
m_name = "XMSS-SHA2_20_512";
m_hash_name = "SHA-512";
m_strength = 512;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_512_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHA2_512;
break;
case XMSS_SHAKE128_W16_H10:
case XMSS_SHAKE_10_256:
m_element_size = 32;
m_w = 16;
m_len = 67;
m_tree_height = 10;
m_name = "XMSS_SHAKE128_W16_H10";
m_name = "XMSS-SHAKE_10_256";
m_hash_name = "SHAKE-128(256)";
m_strength = 256;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE128_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_256;
break;
case XMSS_SHAKE128_W16_H16:
case XMSS_SHAKE_16_256:
m_element_size = 32;
m_w = 16;
m_len = 67;
m_tree_height = 16;
m_name = "XMSS_SHAKE128_W16_H16";
m_name = "XMSS-SHAKE_16_256";
m_hash_name = "SHAKE-128(256)";
m_strength = 256;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE128_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_256;
break;
case XMSS_SHAKE128_W16_H20:
case XMSS_SHAKE_20_256:
m_element_size = 32;
m_w = 16;
m_len = 67;
m_tree_height = 20;
m_name = "XMSS_SHAKE128_W16_H20";
m_name = "XMSS-SHAKE_20_256";
m_hash_name = "SHAKE-128(256)";
m_strength = 256;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE128_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_256;
break;
case XMSS_SHAKE256_W16_H10:
case XMSS_SHAKE_10_512:
m_element_size = 64;
m_w = 16;
m_len = 131;
m_tree_height = 10;
m_name = "XMSS_SHAKE256_W16_H10";
m_name = "XMSS-SHAKE_10_512";
m_hash_name = "SHAKE-256(512)";
m_strength = 512;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE256_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_512;
break;
case XMSS_SHAKE256_W16_H16:
case XMSS_SHAKE_16_512:
m_element_size = 64;
m_w = 16;
m_len = 131;
m_tree_height = 16;
m_name = "XMSS_SHAKE256_W16_H16";
m_name = "XMSS-SHAKE_16_512";
m_hash_name = "SHAKE-256(512)";
m_strength = 512;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE256_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_512;
break;
case XMSS_SHAKE256_W16_H20:
case XMSS_SHAKE_20_512:
m_element_size = 64;
m_w = 16;
m_len = 131;
m_tree_height = 20;
m_name = "XMSS_SHAKE256_W16_H20";
m_name = "XMSS-SHAKE_20_512";
m_hash_name = "SHAKE-256(512)";
m_strength = 512;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE256_W16;
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_512;
break;
default:
throw Not_Implemented("Algorithm id does not match any known XMSS algorithm id.");
Expand Down
Loading

0 comments on commit 7de8754

Please sign in to comment.