Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/pubkey/xmss/xmss_wots_parameters.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XMSS WOTS Parameters
3
 * Descibes a signature method for XMSS Winternitz One Time Signatures,
4
 * as defined in:
5
 * [1] XMSS: Extended Hash-Based Signatures,
6
 *     Request for Comments: 8391
7
 *     Release: May 2018.
8
 *     https://datatracker.ietf.org/doc/rfc8391/
9
 *
10
 * (C) 2016,2017,2018 Matthias Gierlings
11
 *
12
 * Botan is released under the Simplified BSD License (see license.txt)
13
 **/
14
15
#include <botan/xmss_wots_parameters.h>
16
#include <botan/exceptn.h>
17
#include <cmath>
18
19
namespace Botan {
20
21
XMSS_WOTS_Parameters::ots_algorithm_t
22
XMSS_WOTS_Parameters::xmss_wots_id_from_string(const std::string& param_set)
23
0
   {
24
0
   if(param_set == "WOTSP-SHA2_256")
25
0
      { return WOTSP_SHA2_256; }
26
0
   if(param_set == "WOTSP-SHA2_512")
27
0
      { return WOTSP_SHA2_512; }
28
0
   if(param_set == "WOTSP-SHAKE_256")
29
0
      { return WOTSP_SHAKE_256; }
30
0
   if(param_set == "WOTSP-SHAKE_512")
31
0
      { return WOTSP_SHAKE_512; }
32
0
   throw Invalid_Argument("Unknown XMSS-WOTS algorithm param '" + param_set + "'");
33
0
   }
34
35
XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(const std::string& param_set)
36
   : XMSS_WOTS_Parameters(xmss_wots_id_from_string(param_set))
37
0
   {}
38
39
XMSS_WOTS_Parameters::XMSS_WOTS_Parameters(ots_algorithm_t oid)
40
   : m_oid(oid)
41
0
   {
42
0
   switch(oid)
43
0
      {
44
0
      case WOTSP_SHA2_256:
45
0
         m_element_size = 32;
46
0
         m_w = 16;
47
0
         m_len = 67;
48
0
         m_name = "WOTSP-SHA2_256";
49
0
         m_hash_name = "SHA-256";
50
0
         m_strength = 256;
51
0
         break;
52
0
      case WOTSP_SHA2_512:
53
0
         m_element_size = 64;
54
0
         m_w = 16;
55
0
         m_len = 131;
56
0
         m_name = "WOTSP-SHA2_512";
57
0
         m_hash_name = "SHA-512";
58
0
         m_strength = 512;
59
0
         break;
60
0
      case WOTSP_SHAKE_256:
61
0
         m_element_size = 32;
62
0
         m_w = 16;
63
0
         m_len = 67;
64
0
         m_name = "WOTSP-SHAKE_256";
65
0
         m_hash_name = "SHAKE-128(256)";
66
0
         m_strength = 256;
67
0
         break;
68
0
      case WOTSP_SHAKE_512:
69
0
         m_element_size = 64;
70
0
         m_w = 16;
71
0
         m_len = 131;
72
0
         m_name = "WOTSP-SHAKE_512";
73
0
         m_hash_name = "SHAKE-256(512)";
74
0
         m_strength = 512;
75
0
         break;
76
0
      default:
77
0
         throw Not_Implemented("Algorithm id does not match any known XMSS WOTS algorithm id.");
78
0
         break;
79
0
      }
80
0
81
0
   m_lg_w = (m_w == 16) ? 4 : 2;
82
0
   m_len_1 = static_cast<size_t>(std::ceil((8 * element_size()) / m_lg_w));
83
0
   m_len_2 = static_cast<size_t>(
84
0
                floor(log2(m_len_1 * (wots_parameter() - 1)) / m_lg_w) + 1);
85
0
   BOTAN_ASSERT(m_len == m_len_1 + m_len_2, "Invalid XMSS WOTS parameter "
86
0
                "\"len\" detedted.");
87
0
   }
88
89
secure_vector<uint8_t>
90
XMSS_WOTS_Parameters::base_w(const secure_vector<uint8_t>& msg, size_t out_size) const
91
0
   {
92
0
   secure_vector<uint8_t> result;
93
0
   size_t in = 0;
94
0
   size_t total = 0;
95
0
   size_t bits = 0;
96
0
97
0
   for(size_t i = 0; i < out_size; i++)
98
0
      {
99
0
      if(bits == 0)
100
0
         {
101
0
         total = msg[in];
102
0
         in++;
103
0
         bits += 8;
104
0
         }
105
0
      bits -= m_lg_w;
106
0
      result.push_back(static_cast<uint8_t>((total >> bits) & (m_w - 1)));
107
0
      }
108
0
   return result;
109
0
   }
110
111
secure_vector<uint8_t>
112
XMSS_WOTS_Parameters::base_w(size_t value) const
113
0
   {
114
0
   value <<= (8 - ((m_len_2 * m_lg_w) % 8));
115
0
   size_t len_2_bytes = static_cast<size_t>(
116
0
                           std::ceil(static_cast<float>(m_len_2 * m_lg_w) / 8.f));
117
0
   secure_vector<uint8_t> result;
118
0
   XMSS_Tools::concat(result, value, len_2_bytes);
119
0
   return base_w(result, m_len_2);
120
0
   }
121
122
void
123
XMSS_WOTS_Parameters::append_checksum(secure_vector<uint8_t>& data)
124
0
   {
125
0
   size_t csum = 0;
126
0
127
0
   for(size_t i = 0; i < data.size(); i++)
128
0
      {
129
0
      csum += wots_parameter() - 1 - data[i];
130
0
      }
131
0
132
0
   secure_vector<uint8_t> csum_bytes = base_w(csum);
133
0
   std::move(csum_bytes.begin(), csum_bytes.end(), std::back_inserter(data));
134
0
   }
135
136
}